LCOV - code coverage report
Current view: top level - js/src/vm - Runtime.h (source / functions) Hit Total Coverage
Test: output.info Lines: 60 129 46.5 %
Date: 2018-08-07 16:42:27 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       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             : 
       7             : #ifndef vm_Runtime_h
       8             : #define vm_Runtime_h
       9             : 
      10             : #include "mozilla/Atomics.h"
      11             : #include "mozilla/Attributes.h"
      12             : #include "mozilla/DoublyLinkedList.h"
      13             : #include "mozilla/LinkedList.h"
      14             : #include "mozilla/Maybe.h"
      15             : #include "mozilla/MaybeOneOf.h"
      16             : #include "mozilla/MemoryReporting.h"
      17             : #include "mozilla/Scoped.h"
      18             : #include "mozilla/ThreadLocal.h"
      19             : #include "mozilla/Vector.h"
      20             : 
      21             : #include <algorithm>
      22             : #include <setjmp.h>
      23             : 
      24             : #include "builtin/AtomicsObject.h"
      25             : #include "builtin/intl/SharedIntlData.h"
      26             : #include "builtin/Promise.h"
      27             : #include "frontend/BinSourceRuntimeSupport.h"
      28             : #include "frontend/NameCollections.h"
      29             : #include "gc/GCRuntime.h"
      30             : #include "gc/Tracer.h"
      31             : #include "irregexp/RegExpStack.h"
      32             : #include "js/Debug.h"
      33             : #include "js/GCVector.h"
      34             : #include "js/HashTable.h"
      35             : #ifdef DEBUG
      36             : # include "js/Proxy.h" // For AutoEnterPolicy
      37             : #endif
      38             : #include "js/UniquePtr.h"
      39             : #include "js/Vector.h"
      40             : #include "threading/Thread.h"
      41             : #include "vm/Caches.h"
      42             : #include "vm/CodeCoverage.h"
      43             : #include "vm/CommonPropertyNames.h"
      44             : #include "vm/DateTime.h"
      45             : #include "vm/GeckoProfiler.h"
      46             : #include "vm/JSAtom.h"
      47             : #include "vm/JSScript.h"
      48             : #include "vm/Scope.h"
      49             : #include "vm/SharedImmutableStringsCache.h"
      50             : #include "vm/Stack.h"
      51             : #include "vm/Stopwatch.h"
      52             : #include "vm/SymbolType.h"
      53             : #include "wasm/WasmTypes.h"
      54             : 
      55             : namespace js {
      56             : 
      57             : class AutoAssertNoContentJS;
      58             : class AutoKeepAtoms;
      59             : class EnterDebuggeeNoExecute;
      60             : #ifdef JS_TRACE_LOGGING
      61             : class TraceLoggerThread;
      62             : #endif
      63             : 
      64             : } // namespace js
      65             : 
      66             : struct DtoaState;
      67             : 
      68             : #ifdef JS_SIMULATOR_ARM64
      69             : namespace vixl {
      70             : class Simulator;
      71             : }
      72             : #endif
      73             : 
      74             : namespace js {
      75             : 
      76             : extern MOZ_COLD void
      77             : ReportOutOfMemory(JSContext* cx);
      78             : 
      79             : /* Different signature because the return type has MOZ_MUST_USE_TYPE. */
      80             : extern MOZ_COLD mozilla::GenericErrorResult<OOM&>
      81             : ReportOutOfMemoryResult(JSContext* cx);
      82             : 
      83             : extern MOZ_COLD void
      84             : ReportAllocationOverflow(JSContext* maybecx);
      85             : 
      86             : extern MOZ_COLD void
      87             : ReportOverRecursed(JSContext* cx);
      88             : 
      89             : class Activation;
      90             : class ActivationIterator;
      91             : 
      92             : namespace jit {
      93             : class JitRuntime;
      94             : class JitActivation;
      95             : struct PcScriptCache;
      96             : struct AutoFlushICache;
      97             : class CompileRuntime;
      98             : 
      99             : #ifdef JS_SIMULATOR_ARM64
     100             : typedef vixl::Simulator Simulator;
     101             : #elif defined(JS_SIMULATOR)
     102             : class Simulator;
     103             : #endif
     104             : } // namespace jit
     105             : 
     106             : // JS Engine Threading
     107             : //
     108             : // Threads interacting with a runtime are divided into two categories:
     109             : //
     110             : // - The main thread is capable of running JS. There's at most one main thread
     111             : //   per runtime.
     112             : //
     113             : // - Helper threads do not run JS, and are controlled or triggered by activity
     114             : //   on the main thread (or main threads, since all runtimes in a process share
     115             : //   helper threads). Helper threads may have exclusive access to zones created
     116             : //   for them, for parsing and similar tasks, but their activities do not cause
     117             : //   observable changes in script behaviors. Activity on helper threads may be
     118             : //   referred to as happening 'off thread' or on a background thread in some
     119             : //   parts of the VM.
     120             : 
     121             : } /* namespace js */
     122             : 
     123             : namespace JS {
     124             : struct RuntimeSizes;
     125             : } // namespace JS
     126             : 
     127             : /* Various built-in or commonly-used names pinned on first context. */
     128             : struct JSAtomState
     129             : {
     130             : #define PROPERTYNAME_FIELD(idpart, id, text) js::ImmutablePropertyNamePtr id;
     131             :     FOR_EACH_COMMON_PROPERTYNAME(PROPERTYNAME_FIELD)
     132             : #undef PROPERTYNAME_FIELD
     133             : #define PROPERTYNAME_FIELD(name, init, clasp) js::ImmutablePropertyNamePtr name;
     134             :     JS_FOR_EACH_PROTOTYPE(PROPERTYNAME_FIELD)
     135             : #undef PROPERTYNAME_FIELD
     136             : #define PROPERTYNAME_FIELD(name) js::ImmutablePropertyNamePtr name;
     137             :     JS_FOR_EACH_WELL_KNOWN_SYMBOL(PROPERTYNAME_FIELD)
     138             : #undef PROPERTYNAME_FIELD
     139             : #define PROPERTYNAME_FIELD(name) js::ImmutablePropertyNamePtr Symbol_##name;
     140             :     JS_FOR_EACH_WELL_KNOWN_SYMBOL(PROPERTYNAME_FIELD)
     141             : #undef PROPERTYNAME_FIELD
     142             : 
     143             :     js::ImmutablePropertyNamePtr* wellKnownSymbolNames() {
     144             : #define FIRST_PROPERTYNAME_FIELD(name) return &name;
     145           0 :     JS_FOR_EACH_WELL_KNOWN_SYMBOL(FIRST_PROPERTYNAME_FIELD)
     146             : #undef FIRST_PROPERTYNAME_FIELD
     147             :     }
     148             : 
     149             :     js::ImmutablePropertyNamePtr* wellKnownSymbolDescriptions() {
     150             : #define FIRST_PROPERTYNAME_FIELD(name) return &Symbol_ ##name;
     151           0 :     JS_FOR_EACH_WELL_KNOWN_SYMBOL(FIRST_PROPERTYNAME_FIELD)
     152             : #undef FIRST_PROPERTYNAME_FIELD
     153             :     }
     154             : };
     155             : 
     156             : namespace js {
     157             : 
     158             : /*
     159             :  * Storage for well-known symbols. It's a separate struct from the Runtime so
     160             :  * that it can be shared across multiple runtimes. As in JSAtomState, each
     161             :  * field is a smart pointer that's immutable once initialized.
     162             :  * `rt->wellKnownSymbols->iterator` is convertible to Handle<Symbol*>.
     163             :  *
     164             :  * Well-known symbols are never GC'd. The description() of each well-known
     165             :  * symbol is a permanent atom.
     166             :  */
     167             : struct WellKnownSymbols
     168             : {
     169             : #define DECLARE_SYMBOL(name) js::ImmutableSymbolPtr name;
     170             :     JS_FOR_EACH_WELL_KNOWN_SYMBOL(DECLARE_SYMBOL)
     171             : #undef DECLARE_SYMBOL
     172             : 
     173           0 :     const ImmutableSymbolPtr& get(size_t u) const {
     174           0 :         MOZ_ASSERT(u < JS::WellKnownSymbolLimit);
     175           0 :         const ImmutableSymbolPtr* symbols = reinterpret_cast<const ImmutableSymbolPtr*>(this);
     176           0 :         return symbols[u];
     177             :     }
     178             : 
     179             :     const ImmutableSymbolPtr& get(JS::SymbolCode code) const {
     180           0 :         return get(size_t(code));
     181             :     }
     182             : 
     183           0 :     WellKnownSymbols() {}
     184             :     WellKnownSymbols(const WellKnownSymbols&) = delete;
     185             :     WellKnownSymbols& operator=(const WellKnownSymbols&) = delete;
     186             : };
     187             : 
     188             : #define NAME_OFFSET(name)       offsetof(JSAtomState, name)
     189             : 
     190             : inline HandlePropertyName
     191             : AtomStateOffsetToName(const JSAtomState& atomState, size_t offset)
     192             : {
     193           0 :     return *reinterpret_cast<js::ImmutablePropertyNamePtr*>((char*)&atomState + offset);
     194             : }
     195             : 
     196             : // There are several coarse locks in the enum below. These may be either
     197             : // per-runtime or per-process. When acquiring more than one of these locks,
     198             : // the acquisition must be done in the order below to avoid deadlocks.
     199             : enum RuntimeLock {
     200             :     ExclusiveAccessLock,
     201             :     HelperThreadStateLock,
     202             :     GCLock
     203             : };
     204             : 
     205             : inline bool
     206             : CanUseExtraThreads()
     207             : {
     208             :     extern bool gCanUseExtraThreads;
     209           0 :     return gCanUseExtraThreads;
     210             : }
     211             : 
     212             : void DisableExtraThreads();
     213             : 
     214             : using ScriptAndCountsVector = GCVector<ScriptAndCounts, 0, SystemAllocPolicy>;
     215             : 
     216             : class AutoLockForExclusiveAccess;
     217             : class AutoLockScriptData;
     218             : 
     219             : } // namespace js
     220             : 
     221             : struct JSRuntime : public js::MallocProvider<JSRuntime>
     222             : {
     223             :   private:
     224             :     friend class js::Activation;
     225             :     friend class js::ActivationIterator;
     226             :     friend class js::jit::JitActivation;
     227             :     friend class js::jit::CompileRuntime;
     228             : 
     229             :   public:
     230             :     /*
     231             :      * If non-null, another runtime guaranteed to outlive this one and whose
     232             :      * permanent data may be used by this one where possible.
     233             :      */
     234             :     JSRuntime* const parentRuntime;
     235             : 
     236             : #ifdef DEBUG
     237             :     /* The number of child runtimes that have this runtime as their parent. */
     238             :     mozilla::Atomic<size_t> childRuntimeCount;
     239             : 
     240             :     class AutoUpdateChildRuntimeCount
     241             :     {
     242             :         JSRuntime* parent_;
     243             : 
     244             :       public:
     245             :         explicit AutoUpdateChildRuntimeCount(JSRuntime* parent)
     246           0 :           : parent_(parent)
     247             :         {
     248           0 :             if (parent_)
     249           0 :                 parent_->childRuntimeCount++;
     250             :         }
     251             : 
     252             :         ~AutoUpdateChildRuntimeCount() {
     253           0 :             if (parent_)
     254           0 :                 parent_->childRuntimeCount--;
     255             :         }
     256             :     };
     257             : 
     258             :     AutoUpdateChildRuntimeCount updateChildRuntimeCount;
     259             : #endif
     260             : 
     261             :   private:
     262             : #ifdef DEBUG
     263             :     js::WriteOnceData<bool> initialized_;
     264             : #endif
     265             : 
     266             :     // The JSContext* for the runtime's main thread. Immutable after this is set
     267             :     // in JSRuntime::init.
     268             :     JSContext* mainContext_;
     269             : 
     270             :   public:
     271             :     JSContext* mainContextFromAnyThread() const { return mainContext_; }
     272             :     const void* addressOfMainContext() { return &mainContext_; }
     273             : 
     274             :     inline JSContext* mainContextFromOwnThread();
     275             : 
     276             :     /*
     277             :      * The start of the range stored in the profiler sample buffer, as measured
     278             :      * after the most recent sample.
     279             :      * All JitcodeGlobalTable entries referenced from a given sample are
     280             :      * assigned the buffer position of the START of the sample. The buffer
     281             :      * entries that reference the JitcodeGlobalTable entries will only ever be
     282             :      * read from the buffer while the entire sample is still inside the buffer;
     283             :      * if some buffer entries at the start of the sample have left the buffer,
     284             :      * the entire sample will be considered inaccessible.
     285             :      * This means that, once profilerSampleBufferRangeStart_ advances beyond
     286             :      * the sample position that's stored on a JitcodeGlobalTable entry, the
     287             :      * buffer entries that reference this JitcodeGlobalTable entry will be
     288             :      * considered inaccessible, and those JitcodeGlobalTable entry can be
     289             :      * disposed of.
     290             :      */
     291             :     mozilla::Atomic<uint64_t, mozilla::ReleaseAcquire> profilerSampleBufferRangeStart_;
     292             : 
     293           0 :     mozilla::Maybe<uint64_t> profilerSampleBufferRangeStart() {
     294           0 :         if (beingDestroyed_ || !geckoProfiler().enabled()) {
     295             :             return mozilla::Nothing();
     296             :         }
     297           0 :         uint64_t rangeStart = profilerSampleBufferRangeStart_;
     298             :         return mozilla::Some(rangeStart);
     299             :     }
     300             :     void setProfilerSampleBufferRangeStart(uint64_t rangeStart) {
     301           0 :         profilerSampleBufferRangeStart_ = rangeStart;
     302             :     }
     303             : 
     304             :     /* Call this to accumulate telemetry data. */
     305             :     js::MainThreadData<JSAccumulateTelemetryDataCallback> telemetryCallback;
     306             : 
     307             :     /* Call this to accumulate use counter data. */
     308             :     js::MainThreadData<JSSetUseCounterCallback> useCounterCallback;
     309             : 
     310             :   public:
     311             :     // Accumulates data for Firefox telemetry. |id| is the ID of a JS_TELEMETRY_*
     312             :     // histogram. |key| provides an additional key to identify the histogram.
     313             :     // |sample| is the data to add to the histogram.
     314             :     void addTelemetry(int id, uint32_t sample, const char* key = nullptr);
     315             : 
     316             :     void setTelemetryCallback(JSRuntime* rt, JSAccumulateTelemetryDataCallback callback);
     317             : 
     318             :     // Sets the use counter for a specific feature, measuring the presence or
     319             :     // absence of usage of a feature on a specific web page and document which
     320             :     // the passed JSObject belongs to.
     321             :     void setUseCounter(JSObject* obj, JSUseCounter counter);
     322             : 
     323             :     void setUseCounterCallback(JSRuntime* rt, JSSetUseCounterCallback callback);
     324             : 
     325             :   public:
     326             :     js::UnprotectedData<js::OffThreadPromiseRuntimeState> offThreadPromiseState;
     327             :     js::UnprotectedData<JS::ConsumeStreamCallback> consumeStreamCallback;
     328             : 
     329             :     JSObject* getIncumbentGlobal(JSContext* cx);
     330             :     bool enqueuePromiseJob(JSContext* cx, js::HandleFunction job, js::HandleObject promise,
     331             :                            js::HandleObject incumbentGlobal);
     332             :     void addUnhandledRejectedPromise(JSContext* cx, js::HandleObject promise);
     333             :     void removeUnhandledRejectedPromise(JSContext* cx, js::HandleObject promise);
     334             : 
     335             :     js::UnprotectedData<JS::RequestReadableStreamDataCallback> readableStreamDataRequestCallback;
     336             :     js::UnprotectedData<JS::WriteIntoReadRequestBufferCallback> readableStreamWriteIntoReadRequestCallback;
     337             :     js::UnprotectedData<JS::CancelReadableStreamCallback> readableStreamCancelCallback;
     338             :     js::UnprotectedData<JS::ReadableStreamClosedCallback> readableStreamClosedCallback;
     339             :     js::UnprotectedData<JS::ReadableStreamErroredCallback> readableStreamErroredCallback;
     340             :     js::UnprotectedData<JS::ReadableStreamFinalizeCallback> readableStreamFinalizeCallback;
     341             : 
     342             :     /* Had an out-of-memory error which did not populate an exception. */
     343             :     mozilla::Atomic<bool> hadOutOfMemory;
     344             : 
     345             :     /*
     346             :      * Allow relazifying functions in compartments that are active. This is
     347             :      * only used by the relazifyFunctions() testing function.
     348             :      */
     349             :     js::MainThreadData<bool> allowRelazificationForTesting;
     350             : 
     351             :     /* Compartment destroy callback. */
     352             :     js::MainThreadData<JSDestroyCompartmentCallback> destroyCompartmentCallback;
     353             : 
     354             :     /* Compartment memory reporting callback. */
     355             :     js::MainThreadData<JSSizeOfIncludingThisCompartmentCallback> sizeOfIncludingThisCompartmentCallback;
     356             : 
     357             :     /* Realm destroy callback. */
     358             :     js::MainThreadData<JS::DestroyRealmCallback> destroyRealmCallback;
     359             : 
     360             :     /* Call this to get the name of a realm. */
     361             :     js::MainThreadData<JS::RealmNameCallback> realmNameCallback;
     362             : 
     363             :     /* Callback for doing memory reporting on external strings. */
     364             :     js::MainThreadData<JSExternalStringSizeofCallback> externalStringSizeofCallback;
     365             : 
     366             :     js::MainThreadData<mozilla::UniquePtr<js::SourceHook>> sourceHook;
     367             : 
     368             :     js::MainThreadData<const JSSecurityCallbacks*> securityCallbacks;
     369             :     js::MainThreadData<const js::DOMCallbacks*> DOMcallbacks;
     370             :     js::MainThreadData<JSDestroyPrincipalsOp> destroyPrincipals;
     371             :     js::MainThreadData<JSReadPrincipalsOp> readPrincipals;
     372             : 
     373             :     /* Optional warning reporter. */
     374             :     js::MainThreadData<JS::WarningReporter> warningReporter;
     375             : 
     376             :   private:
     377             :     /* Gecko profiling metadata */
     378             :     js::UnprotectedData<js::GeckoProfilerRuntime> geckoProfiler_;
     379             :   public:
     380       32654 :     js::GeckoProfilerRuntime& geckoProfiler() { return geckoProfiler_.ref(); }
     381             : 
     382             :     // Heap GC roots for PersistentRooted pointers.
     383             :     js::MainThreadData<mozilla::EnumeratedArray<JS::RootKind, JS::RootKind::Limit,
     384             :                                                  mozilla::LinkedList<JS::PersistentRooted<void*>>>> heapRoots;
     385             : 
     386             :     void tracePersistentRoots(JSTracer* trc);
     387             :     void finishPersistentRoots();
     388             : 
     389             :     void finishRoots();
     390             : 
     391             :   public:
     392             :     js::UnprotectedData<JS::BuildIdOp> buildIdOp;
     393             : 
     394             :     /* AsmJSCache callbacks are runtime-wide. */
     395             :     js::UnprotectedData<JS::AsmJSCacheOps> asmJSCacheOps;
     396             : 
     397             :   private:
     398             :     js::UnprotectedData<const JSPrincipals*> trustedPrincipals_;
     399             :   public:
     400           2 :     void setTrustedPrincipals(const JSPrincipals* p) { trustedPrincipals_ = p; }
     401       34474 :     const JSPrincipals* trustedPrincipals() const { return trustedPrincipals_; }
     402             : 
     403             :     js::MainThreadData<const JSWrapObjectCallbacks*> wrapObjectCallbacks;
     404             :     js::MainThreadData<js::PreserveWrapperCallback> preserveWrapperCallback;
     405             : 
     406             :     js::MainThreadData<js::ScriptEnvironmentPreparer*> scriptEnvironmentPreparer;
     407             : 
     408             :     js::MainThreadData<js::CTypesActivityCallback> ctypesActivityCallback;
     409             : 
     410             :   private:
     411             :     js::WriteOnceData<const js::Class*> windowProxyClass_;
     412             : 
     413             :   public:
     414             :     const js::Class* maybeWindowProxyClass() const {
     415      124654 :         return windowProxyClass_;
     416             :     }
     417             :     void setWindowProxyClass(const js::Class* clasp) {
     418           0 :         windowProxyClass_ = clasp;
     419             :     }
     420             : 
     421             :   private:
     422             :     // List of non-ephemeron weak containers to sweep during beginSweepingSweepGroup.
     423             :     js::MainThreadData<mozilla::LinkedList<JS::detail::WeakCacheBase>> weakCaches_;
     424             :   public:
     425           0 :     mozilla::LinkedList<JS::detail::WeakCacheBase>& weakCaches() { return weakCaches_.ref(); }
     426             :     void registerWeakCache(JS::detail::WeakCacheBase* cachep) {
     427           0 :         weakCaches().insertBack(cachep);
     428             :     }
     429             : 
     430             :     template <typename T>
     431             :     struct GlobalObjectWatchersLinkAccess {
     432             :       static mozilla::DoublyLinkedListElement<T>& Get(T* aThis) {
     433             :         return aThis->onNewGlobalObjectWatchersLink;
     434             :       }
     435             :     };
     436             : 
     437             :     using WatchersList =
     438             :         mozilla::DoublyLinkedList<js::Debugger,
     439             :                                   GlobalObjectWatchersLinkAccess<js::Debugger>>;
     440             :   private:
     441             :     /*
     442             :      * List of all enabled Debuggers that have onNewGlobalObject handler
     443             :      * methods established.
     444             :      */
     445             :     js::MainThreadData<WatchersList> onNewGlobalObjectWatchers_;
     446             : 
     447             :   public:
     448          42 :     WatchersList& onNewGlobalObjectWatchers() { return onNewGlobalObjectWatchers_.ref(); }
     449             : 
     450             :   private:
     451             :     /* Linked list of all Debugger objects in the runtime. */
     452             :     js::MainThreadData<mozilla::LinkedList<js::Debugger>> debuggerList_;
     453             :   public:
     454           4 :     mozilla::LinkedList<js::Debugger>& debuggerList() { return debuggerList_.ref(); }
     455             : 
     456             :   private:
     457             :     /*
     458             :      * Lock taken when using per-runtime or per-zone data that could otherwise
     459             :      * be accessed simultaneously by multiple threads.
     460             :      *
     461             :      * Locking this only occurs if there is actually a thread other than the
     462             :      * main thread which could access such data.
     463             :      */
     464             :     js::Mutex exclusiveAccessLock;
     465             : #ifdef DEBUG
     466             :     bool activeThreadHasExclusiveAccess;
     467             : #endif
     468             : 
     469             :     /*
     470             :      * Lock used to protect the script data table, which can be used by
     471             :      * off-thread parsing.
     472             :      *
     473             :      * Locking this only occurs if there is actually a thread other than the
     474             :      * main thread which could access this.
     475             :      */
     476             :     js::Mutex scriptDataLock;
     477             : #ifdef DEBUG
     478             :     bool activeThreadHasScriptDataAccess;
     479             : #endif
     480             : 
     481             :     // Number of zones which may be operated on by helper threads.
     482             :     mozilla::Atomic<size_t> numActiveHelperThreadZones;
     483             : 
     484             :     // Any GC activity affecting the heap.
     485             :     mozilla::Atomic<JS::HeapState> heapState_;
     486             : 
     487             :     friend class js::AutoLockForExclusiveAccess;
     488             :     friend class js::AutoLockScriptData;
     489             : 
     490             :   public:
     491             :     void setUsedByHelperThread(JS::Zone* zone);
     492      943810 :     void clearUsedByHelperThread(JS::Zone* zone);
     493             : 
     494             :     bool hasHelperThreadZones() const {
     495             :         return numActiveHelperThreadZones > 0;
     496      286037 :     }
     497      286037 : 
     498      276702 : #ifdef DEBUG
     499             :     bool currentThreadHasExclusiveAccess() const {
     500           0 :         if (!hasHelperThreadZones())
     501             :             return CurrentThreadCanAccessRuntime(this) && activeThreadHasExclusiveAccess;
     502             : 
     503           0 :         return exclusiveAccessLock.ownedByCurrentThread();
     504       25412 :     }
     505       24685 : 
     506             :     bool currentThreadHasScriptDataAccess() const {
     507           0 :         if (!hasHelperThreadZones())
     508             :             return CurrentThreadCanAccessRuntime(this) && activeThreadHasScriptDataAccess;
     509             : 
     510             :         return scriptDataLock.ownedByCurrentThread();
     511             :     }
     512             : #endif
     513             : 
     514             :     JS::HeapState heapState() const {
     515             :         return heapState_;
     516             :     }
     517             : 
     518             :     // How many realms there are across all zones. This number includes
     519             :     // off-thread context realms, so it isn't necessarily equal to the
     520             :     // number of realms visited by RealmsIter.
     521             :     js::MainThreadData<size_t> numRealms;
     522             : 
     523             :     /* Locale-specific callbacks for string conversion. */
     524             :     js::MainThreadData<const JSLocaleCallbacks*> localeCallbacks;
     525             : 
     526             :     /* Default locale for Internationalization API */
     527             :     js::MainThreadData<char*> defaultLocale;
     528             : 
     529             :     /* If true, new scripts must be created with PC counter information. */
     530             :     js::MainThreadOrIonCompileData<bool> profilingScripts;
     531             : 
     532       40516 :     /* Strong references on scripts held for PCCount profiling API. */
     533             :     js::MainThreadData<JS::PersistentRooted<js::ScriptAndCountsVector>*> scriptAndCountsVector;
     534             : 
     535             :   private:
     536             :     /* Code coverage output. */
     537             :     js::UnprotectedData<js::coverage::LCovRuntime> lcovOutput_;
     538             :   public:
     539             :     js::coverage::LCovRuntime& lcovOutput() { return lcovOutput_.ref(); }
     540             : 
     541             :   private:
     542             :     js::UnprotectedData<js::jit::JitRuntime*> jitRuntime_;
     543             : 
     544             :     /*
     545             :      * Self-hosting state cloned on demand into other compartments. Shared with the parent
     546             :      * runtime if there is one.
     547             :      */
     548             :     js::WriteOnceData<js::NativeObject*> selfHostingGlobal_;
     549             : 
     550             :     static js::GlobalObject*
     551             :     createSelfHostingGlobal(JSContext* cx);
     552             : 
     553          14 :     bool getUnclonedSelfHostedValue(JSContext* cx, js::HandlePropertyName name,
     554          38 :                                     js::MutableHandleValue vp);
     555             :     JSFunction* getUnclonedSelfHostedFunction(JSContext* cx, js::HandlePropertyName name);
     556             : 
     557           0 :     js::jit::JitRuntime* createJitRuntime(JSContext* cx);
     558             : 
     559             :   public:
     560           0 :     js::jit::JitRuntime* getJitRuntime(JSContext* cx) {
     561             :         return jitRuntime_ ? jitRuntime_.ref() : createJitRuntime(cx);
     562             :     }
     563             :     js::jit::JitRuntime* jitRuntime() const {
     564             :         return jitRuntime_.ref();
     565             :     }
     566             :     bool hasJitRuntime() const {
     567             :         return !!jitRuntime_;
     568             :     }
     569             : 
     570             :   private:
     571             :     // Used to generate random keys for hash tables.
     572             :     mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG> randomKeyGenerator_;
     573             :     mozilla::non_crypto::XorShift128PlusRNG& randomKeyGenerator();
     574             : 
     575             :     // Used to generate random hash codes for symbols.
     576             :     mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG> randomHashCodeGenerator_;
     577             : 
     578             :   public:
     579             :     mozilla::HashCodeScrambler randomHashCodeScrambler();
     580             :     mozilla::non_crypto::XorShift128PlusRNG forkRandomKeyGenerator();
     581             : 
     582          96 :     js::HashNumber randomHashCode();
     583             : 
     584             :     //-------------------------------------------------------------------------
     585             :     // Self-hosting support
     586             :     //-------------------------------------------------------------------------
     587             : 
     588             :     bool hasInitializedSelfHosting() const {
     589      231912 :         return selfHostingGlobal_;
     590             :     }
     591             : 
     592             :     bool initSelfHosting(JSContext* cx);
     593             :     void finishSelfHosting();
     594             :     void traceSelfHostingGlobal(JSTracer* trc);
     595             :     bool isSelfHostingGlobal(JSObject* global) {
     596             :         return global == selfHostingGlobal_;
     597             :     }
     598             :     bool isSelfHostingZone(const JS::Zone* zone) const;
     599             :     bool createLazySelfHostedFunctionClone(JSContext* cx, js::HandlePropertyName selfHostedName,
     600             :                                            js::HandleAtom name, unsigned nargs,
     601             :                                            js::HandleObject proto,
     602             :                                            js::NewObjectKind newKind,
     603             :                                            js::MutableHandleFunction fun);
     604             :     bool cloneSelfHostedFunctionScript(JSContext* cx, js::Handle<js::PropertyName*> name,
     605             :                                        js::Handle<JSFunction*> targetFun);
     606             :     bool cloneSelfHostedValue(JSContext* cx, js::Handle<js::PropertyName*> name,
     607             :                               js::MutableHandleValue vp);
     608             :     void assertSelfHostedFunctionHasCanonicalName(JSContext* cx, js::HandlePropertyName name);
     609             : 
     610             :     //-------------------------------------------------------------------------
     611             :     // Locale information
     612             :     //-------------------------------------------------------------------------
     613             : 
     614             :     /*
     615             :      * Set the default locale for the ECMAScript Internationalization API
     616             :      * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat).
     617             :      * Note that the Internationalization API encourages clients to
     618             :      * specify their own locales.
     619             :      * The locale string remains owned by the caller.
     620             :      */
     621             :     bool setDefaultLocale(const char* locale);
     622             : 
     623             :     /* Reset the default locale to OS defaults. */
     624             :     void resetDefaultLocale();
     625             : 
     626             :     /* Gets current default locale. String remains owned by context. */
     627             :     const char* getDefaultLocale();
     628          82 : 
     629             :     /* Garbage collector state. */
     630             :     js::gc::GCRuntime   gc;
     631             : 
     632             :     /* Garbage collector state has been successfully initialized. */
     633             :     js::WriteOnceData<bool> gcInitialized;
     634             : 
     635             :     bool hasZealMode(js::gc::ZealMode mode) { return gc.hasZealMode(mode); }
     636             : 
     637             :     void lockGC() {
     638             :         gc.lockGC();
     639             :     }
     640             : 
     641             :     void unlockGC() {
     642             :         gc.unlockGC();
     643             :     }
     644             : 
     645             :     /* Well-known numbers. */
     646             :     const js::Value     NaNValue;
     647             :     const js::Value     negativeInfinityValue;
     648             :     const js::Value     positiveInfinityValue;
     649      130214 : 
     650      260428 :     js::WriteOnceData<js::PropertyName*> emptyString;
     651      260428 : 
     652             :   private:
     653             :     js::WriteOnceData<js::FreeOp*> defaultFreeOp_;
     654             : 
     655             :   public:
     656             :     js::FreeOp* defaultFreeOp() {
     657             :         MOZ_ASSERT(defaultFreeOp_);
     658             :         return defaultFreeOp_;
     659             :     }
     660             : 
     661             : #if !EXPOSE_INTL_API
     662             :     /* Number localization, used by jsnum.cpp. */
     663             :     js::WriteOnceData<const char*> thousandsSeparator;
     664             :     js::WriteOnceData<const char*> decimalSeparator;
     665             :     js::WriteOnceData<const char*> numGrouping;
     666             : #endif
     667             : 
     668           0 :   private:
     669             :     mozilla::Maybe<js::SharedImmutableStringsCache> sharedImmutableStrings_;
     670             : 
     671             :   public:
     672             :     // If this particular JSRuntime has a SharedImmutableStringsCache, return a
     673        1011 :     // pointer to it, otherwise return nullptr.
     674        1143 :     js::SharedImmutableStringsCache* maybeThisRuntimeSharedImmutableStrings() {
     675        2088 :         return sharedImmutableStrings_.isSome() ? &*sharedImmutableStrings_ : nullptr;
     676           0 :     }
     677             : 
     678             :     // Get a reference to this JSRuntime's or its parent's
     679             :     // SharedImmutableStringsCache.
     680             :     js::SharedImmutableStringsCache& sharedImmutableStrings() {
     681             :         MOZ_ASSERT_IF(parentRuntime, !sharedImmutableStrings_);
     682             :         MOZ_ASSERT_IF(!parentRuntime, sharedImmutableStrings_);
     683           0 :         return parentRuntime ? parentRuntime->sharedImmutableStrings() : *sharedImmutableStrings_;
     684             :     }
     685             : 
     686             :   private:
     687             :     js::WriteOnceData<bool> beingDestroyed_;
     688             :   public:
     689             :     bool isBeingDestroyed() const {
     690             :         return beingDestroyed_;
     691             :     }
     692             : 
     693             :   private:
     694             :     bool allowContentJS_;
     695             :   public:
     696             :     bool allowContentJS() const {
     697             :         return allowContentJS_;
     698             :     }
     699             : 
     700             :     friend class js::AutoAssertNoContentJS;
     701             : 
     702             :   private:
     703             :     // Set of all atoms other than those in permanentAtoms and staticStrings.
     704             :     // Reading or writing this set requires the calling thread to use
     705             :     // AutoLockForExclusiveAccess.
     706             :     js::ExclusiveAccessLockOrGCTaskData<js::AtomSet*> atoms_;
     707             : 
     708             :     // Set of all atoms added while the main atoms table is being swept.
     709             :     js::ExclusiveAccessLockData<js::AtomSet*> atomsAddedWhileSweeping_;
     710             : 
     711             :     // Set of all live symbols produced by Symbol.for(). All such symbols are
     712           0 :     // allocated in the atomsZone. Reading or writing the symbol registry
     713             :     // requires the calling thread to use AutoLockForExclusiveAccess.
     714           0 :     js::ExclusiveAccessLockOrGCTaskData<js::SymbolRegistry> symbolRegistry_;
     715           0 : 
     716           0 :   public:
     717             :     bool initializeAtoms(JSContext* cx);
     718             :     void finishAtoms();
     719           0 :     bool atomsAreFinished() const { return !atoms_; }
     720      133362 : 
     721      133364 :     js::AtomSet* atomsForSweeping() {
     722             :         MOZ_ASSERT(JS::RuntimeHeapIsCollecting());
     723           0 :         return atoms_;
     724           0 :     }
     725           0 : 
     726             :     js::AtomSet& atoms(js::AutoLockForExclusiveAccess& lock) {
     727             :         MOZ_ASSERT(atoms_);
     728             :         return *atoms_;
     729             :     }
     730             :     js::AtomSet& unsafeAtoms() {
     731      133364 :         MOZ_ASSERT(atoms_);
     732             :         return *atoms_;
     733             :     }
     734             : 
     735             :     bool createAtomsAddedWhileSweepingTable();
     736             :     void destroyAtomsAddedWhileSweepingTable();
     737             :     js::AtomSet* atomsAddedWhileSweeping() {
     738       97200 :         return atomsAddedWhileSweeping_;
     739             :     }
     740             : 
     741           0 :     const JS::Zone* atomsZone(const js::AutoLockForExclusiveAccess& lock) const {
     742             :         return gc.atomsZone;
     743             :     }
     744             :     JS::Zone* atomsZone(const js::AutoLockForExclusiveAccess& lock) {
     745    40195840 :         return gc.atomsZone;
     746             :     }
     747             :     JS::Zone* unsafeAtomsZone() {
     748             :         return gc.atomsZone;
     749             :     }
     750             : 
     751           0 :     bool isAtomsZone(const JS::Zone* zone) const {
     752             :         return zone == gc.atomsZone;
     753             :     }
     754           0 : 
     755             :     bool activeGCInAtomsZone();
     756             : 
     757             :     js::SymbolRegistry& symbolRegistry(js::AutoLockForExclusiveAccess& lock) {
     758             :         return symbolRegistry_.ref();
     759             :     }
     760             :     js::SymbolRegistry& unsafeSymbolRegistry() {
     761             :         return symbolRegistry_.ref();
     762             :     }
     763             : 
     764             :     // Permanent atoms are fixed during initialization of the runtime and are
     765             :     // not modified or collected until the runtime is destroyed. These may be
     766             :     // shared with another, longer living runtime through |parentRuntime| and
     767             :     // can be freely accessed with no locking necessary.
     768             : 
     769             :     // Permanent atoms pre-allocated for general use.
     770             :     js::WriteOnceData<js::StaticStrings*> staticStrings;
     771             : 
     772             :     // Cached pointers to various permanent property names.
     773             :     js::WriteOnceData<JSAtomState*> commonNames;
     774             : 
     775             :     // All permanent atoms in the runtime, other than those in staticStrings.
     776             :     // Unlike |atoms_|, access to this does not require
     777             :     // AutoLockForExclusiveAccess because it is frozen and thus read-only.
     778             :     js::WriteOnceData<js::FrozenAtomSet*> permanentAtoms;
     779             : 
     780             :     bool transformToPermanentAtoms(JSContext* cx);
     781             : 
     782             :     // Cached well-known symbols (ES6 rev 24 6.1.5.1). Like permanent atoms,
     783             :     // these are shared with the parentRuntime, if any.
     784             :     js::WriteOnceData<js::WellKnownSymbols*> wellKnownSymbols;
     785             : 
     786             :     /* Shared Intl data for this runtime. */
     787             :     js::MainThreadData<js::intl::SharedIntlData> sharedIntlData;
     788             : 
     789             :     void traceSharedIntlData(JSTracer* trc);
     790             : 
     791       26400 :     // Table of bytecode and other data that may be shared across scripts
     792             :     // within the runtime. This may be modified by threads using
     793             :     // AutoLockForExclusiveAccess.
     794             :   private:
     795             :     js::ScriptDataLockData<js::ScriptDataTable> scriptDataTable_;
     796             :   public:
     797             :     js::ScriptDataTable& scriptDataTable(const js::AutoLockScriptData& lock) {
     798             :         return scriptDataTable_.ref();
     799             :     }
     800             : 
     801             :     js::WriteOnceData<bool> jitSupportsFloatingPoint;
     802             :     js::WriteOnceData<bool> jitSupportsUnalignedAccesses;
     803           1 :     js::WriteOnceData<bool> jitSupportsSimd;
     804             : 
     805             :   private:
     806             :     static mozilla::Atomic<size_t> liveRuntimesCount;
     807             : 
     808             :   public:
     809             :     static bool hasLiveRuntimes() {
     810             :         return liveRuntimesCount > 0;
     811             :     }
     812             : 
     813             :     explicit JSRuntime(JSRuntime* parentRuntime);
     814             :     ~JSRuntime();
     815             : 
     816             :     // destroyRuntime is used instead of a destructor, to ensure the downcast
     817             :     // to JSContext remains valid. The final GC triggered here depends on this.
     818             :     void destroyRuntime();
     819             : 
     820             :     bool init(JSContext* cx, uint32_t maxbytes, uint32_t maxNurseryBytes);
     821             : 
     822             :     JSRuntime* thisFromCtor() { return this; }
     823             : 
     824             :   public:
     825             :     /*
     826             :      * Call this after allocating memory held by GC things, to update memory
     827             :      * pressure counters or report the OOM error if necessary. If oomError and
     828           0 :      * cx is not null the function also reports OOM error.
     829             :      *
     830             :      * The function must be called outside the GC lock and in case of OOM error
     831             :      * the caller must ensure that no deadlock possible during OOM reporting.
     832             :      */
     833             :     void updateMallocCounter(size_t nbytes);
     834             : 
     835             :     void reportAllocationOverflow() { js::ReportAllocationOverflow(nullptr); }
     836             : 
     837             :     /*
     838             :      * This should be called after system malloc/calloc/realloc returns nullptr
     839             :      * to try to recove some memory or to report an error.  For realloc, the
     840             :      * original pointer must be passed as reallocPtr.
     841             :      *
     842             :      * The function must be called outside the GC lock.
     843             :      */
     844             :     JS_FRIEND_API(void*) onOutOfMemory(js::AllocFunction allocator, size_t nbytes,
     845             :                                        void* reallocPtr = nullptr, JSContext* maybecx = nullptr);
     846             : 
     847             :     /*  onOutOfMemory but can call OnLargeAllocationFailure. */
     848             :     JS_FRIEND_API(void*) onOutOfMemoryCanGC(js::AllocFunction allocator, size_t nbytes,
     849             :                                             void* reallocPtr = nullptr);
     850             : 
     851             :     static const unsigned LARGE_ALLOCATION = 25 * 1024 * 1024;
     852             : 
     853             :     void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::RuntimeSizes* rtSizes);
     854             : 
     855             :   private:
     856             :     // Settings for how helper threads can be used.
     857             :     mozilla::Atomic<bool> offthreadIonCompilationEnabled_;
     858             :     mozilla::Atomic<bool> parallelParsingEnabled_;
     859             : 
     860           4 :     js::MainThreadData<bool> autoWritableJitCodeActive_;
     861             : 
     862             :   public:
     863           0 : 
     864             :     // Note: these values may be toggled dynamically (in response to about:config
     865             :     // prefs changing).
     866           0 :     void setOffthreadIonCompilationEnabled(bool value) {
     867             :         offthreadIonCompilationEnabled_ = value;
     868             :     }
     869           0 :     bool canUseOffthreadIonCompilation() const {
     870             :         return offthreadIonCompilationEnabled_;
     871             :     }
     872           0 :     void setParallelParsingEnabled(bool value) {
     873       11260 :         parallelParsingEnabled_ = value;
     874       11260 :     }
     875           0 :     bool canUseParallelParsing() const {
     876             :         return parallelParsingEnabled_;
     877             :     }
     878             : 
     879             :     void toggleAutoWritableJitCodeActive(bool b) {
     880             :         MOZ_ASSERT(autoWritableJitCodeActive_ != b, "AutoWritableJitCode should not be nested.");
     881             :         autoWritableJitCodeActive_ = b;
     882             :     }
     883             : 
     884             :     /* See comment for JS::SetOutOfMemoryCallback in jsapi.h. */
     885             :     js::MainThreadData<JS::OutOfMemoryCallback> oomCallback;
     886             :     js::MainThreadData<void*> oomCallbackData;
     887             : 
     888             :     /*
     889             :      * Debugger.Memory functions like takeCensus use this embedding-provided
     890             :      * function to assess the size of malloc'd blocks of memory.
     891             :      */
     892             :     js::MainThreadData<mozilla::MallocSizeOf> debuggerMallocSizeOf;
     893       33141 : 
     894             :     /* Last time at which an animation was played for this runtime. */
     895             :     mozilla::Atomic<int64_t> lastAnimationTime;
     896             : 
     897             :   private:
     898             :     js::MainThreadData<js::PerformanceMonitoring> performanceMonitoring_;
     899             :   public:
     900             :     js::PerformanceMonitoring& performanceMonitoring() { return performanceMonitoring_.ref(); }
     901          12 : 
     902          12 :   private:
     903          12 :     /* The stack format for the current runtime.  Only valid on non-child
     904           0 :      * runtimes. */
     905           0 :     mozilla::Atomic<js::StackFormat, mozilla::ReleaseAcquire> stackFormat_;
     906             : 
     907           0 :   public:
     908           0 :     js::StackFormat stackFormat() const {
     909             :         const JSRuntime* rt = this;
     910           0 :         while (rt->parentRuntime) {
     911           0 :             MOZ_ASSERT(rt->stackFormat_ == js::StackFormat::Default);
     912           0 :             rt = rt->parentRuntime;
     913           0 :         }
     914           0 :         MOZ_ASSERT(rt->stackFormat_ != js::StackFormat::Default);
     915             :         return rt->stackFormat_;
     916             :     }
     917             :     void setStackFormat(js::StackFormat format) {
     918             :         MOZ_ASSERT(!parentRuntime);
     919             :         MOZ_ASSERT(format != js::StackFormat::Default);
     920             :         stackFormat_ = format;
     921             :     }
     922             : 
     923       97444 :     // For inherited heap state accessors.
     924             :     friend class js::gc::AutoTraceSession;
     925             :     friend class JS::AutoEnterCycleCollection;
     926             : 
     927             :   private:
     928             :     js::MainThreadData<js::RuntimeCaches> caches_;
     929             :   public:
     930             :     js::RuntimeCaches& caches() { return caches_.ref(); }
     931             : 
     932             :     // List of all the live wasm::Instances in the runtime. Equal to the union
     933             :     // of all instances registered in all JS::Realms. Accessed from watchdog
     934             :     // threads for purposes of wasm::InterruptRunningCode().
     935             :     js::ExclusiveData<js::wasm::InstanceVector> wasmInstances;
     936             : 
     937             :     // The implementation-defined abstract operation HostResolveImportedModule.
     938             :     js::MainThreadData<JS::ModuleResolveHook> moduleResolveHook;
     939             : 
     940           0 :     // A hook that implements the abstract operations
     941             :     // HostGetImportMetaProperties and HostFinalizeImportMeta.
     942             :     js::MainThreadData<JS::ModuleMetadataHook> moduleMetadataHook;
     943             : 
     944             :   public:
     945             : #if defined(JS_BUILD_BINAST)
     946             :     js::BinaryASTSupport& binast() {
     947             :         return binast_;
     948             :     }
     949             :   private:
     950             :     js::BinaryASTSupport binast_;
     951             : #endif // defined(JS_BUILD_BINAST)
     952             : 
     953             :   public:
     954             : #if defined(NIGHTLY_BUILD)
     955           4 :     // Support for informing the embedding of any error thrown.
     956           4 :     // This mechanism is designed to let the embedding
     957             :     // log/report/fail in case certain errors are thrown
     958             :     // (e.g. SyntaxError, ReferenceError or TypeError
     959             :     // in critical code).
     960             :     struct ErrorInterceptionSupport {
     961             :         ErrorInterceptionSupport()
     962             :           : isExecuting(false)
     963             :           , interceptor(nullptr)
     964             :         { }
     965             : 
     966             :         // true if the error interceptor is currently executing,
     967             :         // false otherwise. Used to avoid infinite loops.
     968             :         bool isExecuting;
     969             : 
     970             :         // if non-null, any call to `setPendingException`
     971             :         // in this runtime will trigger the call to `interceptor`
     972             :         JSErrorInterceptor* interceptor;
     973             :     };
     974             :     ErrorInterceptionSupport errorInterception;
     975             : #endif // defined(NIGHTLY_BUILD)
     976             : };
     977             : 
     978             : namespace js {
     979             : 
     980             : /*
     981             :  * RAII class that takes the GC lock while it is live.
     982             :  *
     983             :  * Usually functions will pass const references of this class.  However
     984             :  * non-const references can be used to either temporarily release the lock by
     985             :  * use of AutoUnlockGC or to start background allocation when the lock is
     986       16824 :  * released.
     987             :  */
     988       11216 : class MOZ_RAII AutoLockGC
     989           0 : {
     990             :   public:
     991             :     explicit AutoLockGC(JSRuntime* rt
     992           0 :                         MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     993        5608 :       : runtime_(rt)
     994        5608 :     {
     995             :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     996           0 :         lock();
     997           0 :     }
     998        5628 : 
     999           0 :     ~AutoLockGC() {
    1000             :         lockGuard_.reset();
    1001           0 :     }
    1002           0 : 
    1003        5412 :     void lock() {
    1004           0 :         MOZ_ASSERT(lockGuard_.isNothing());
    1005             :         lockGuard_.emplace(runtime_->gc.lock);
    1006             :     }
    1007           0 : 
    1008             :     void unlock() {
    1009             :         MOZ_ASSERT(lockGuard_.isSome());
    1010             :         lockGuard_.reset();
    1011             :     }
    1012             : 
    1013             :     js::LockGuard<js::Mutex>& guard() {
    1014             :         return lockGuard_.ref();
    1015             :     }
    1016             : 
    1017             :   protected:
    1018             :     JSRuntime* runtime() const { return runtime_; }
    1019             : 
    1020             :   private:
    1021             :     JSRuntime* runtime_;
    1022             :     mozilla::Maybe<js::LockGuard<js::Mutex>> lockGuard_;
    1023             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
    1024             : 
    1025             :     AutoLockGC(const AutoLockGC&) = delete;
    1026             :     AutoLockGC& operator=(const AutoLockGC&) = delete;
    1027             : };
    1028             : 
    1029             : /*
    1030        5392 :  * Same as AutoLockGC except it can optionally start a background chunk
    1031       10784 :  * allocation task when the lock is released.
    1032             :  */
    1033             : class MOZ_RAII AutoLockGCBgAlloc : public AutoLockGC
    1034           0 : {
    1035        5392 :   public:
    1036             :     explicit AutoLockGCBgAlloc(JSRuntime* rt)
    1037             :       : AutoLockGC(rt)
    1038             :       , startBgAlloc(false)
    1039             :     {}
    1040             : 
    1041             :     ~AutoLockGCBgAlloc() {
    1042        5392 :         unlock();
    1043          20 : 
    1044        5392 :         /*
    1045             :          * We have to do this after releasing the lock because it may acquire
    1046             :          * the helper lock which could cause lock inversion if we still held
    1047             :          * the GC lock.
    1048             :          */
    1049             :         if (startBgAlloc)
    1050             :             runtime()->gc.startBackgroundAllocTaskIfIdle();
    1051             :     }
    1052             : 
    1053          20 :     /*
    1054             :      * This can be used to start a background allocation task (if one isn't
    1055             :      * already running) that allocates chunks and makes them available in the
    1056             :      * free chunks list.  This happens after the lock is released in order to
    1057             :      * avoid lock inversion.
    1058             :      */
    1059             :     void tryToStartBackgroundAllocation() {
    1060             :         startBgAlloc = true;
    1061             :     }
    1062             : 
    1063             :   private:
    1064             :     // true if we should start a background chunk allocation task after the
    1065             :     // lock is released.
    1066             :     bool startBgAlloc;
    1067          40 : };
    1068             : 
    1069          40 : class MOZ_RAII AutoUnlockGC
    1070           0 : {
    1071             :   public:
    1072             :     explicit AutoUnlockGC(AutoLockGC& lock
    1073           0 :                           MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
    1074          20 :       : lock(lock)
    1075             :     {
    1076             :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
    1077             :         lock.unlock();
    1078             :     }
    1079             : 
    1080             :     ~AutoUnlockGC() {
    1081             :         lock.lock();
    1082             :     }
    1083             : 
    1084             :   private:
    1085             :     AutoLockGC& lock;
    1086             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
    1087             : 
    1088             :     AutoUnlockGC(const AutoUnlockGC&) = delete;
    1089             :     AutoUnlockGC& operator=(const AutoUnlockGC&) = delete;
    1090             : };
    1091             : 
    1092             : /************************************************************************/
    1093             : 
    1094             : static MOZ_ALWAYS_INLINE void
    1095             : MakeRangeGCSafe(Value* vec, size_t len)
    1096             : {
    1097             :     // Don't PodZero here because JS::Value is non-trivial.
    1098             :     for (size_t i = 0; i < len; i++)
    1099             :         vec[i].setDouble(+0.0);
    1100             : }
    1101             : 
    1102             : static MOZ_ALWAYS_INLINE void
    1103             : MakeRangeGCSafe(Value* beg, Value* end)
    1104             : {
    1105             :     MakeRangeGCSafe(beg, end - beg);
    1106             : }
    1107             : 
    1108             : static MOZ_ALWAYS_INLINE void
    1109             : MakeRangeGCSafe(jsid* beg, jsid* end)
    1110             : {
    1111             :     std::fill(beg, end, INT_TO_JSID(0));
    1112             : }
    1113             : 
    1114             : static MOZ_ALWAYS_INLINE void
    1115             : MakeRangeGCSafe(jsid* vec, size_t len)
    1116             : {
    1117             :     MakeRangeGCSafe(vec, vec + len);
    1118             : }
    1119             : 
    1120             : static MOZ_ALWAYS_INLINE void
    1121             : MakeRangeGCSafe(Shape** beg, Shape** end)
    1122             : {
    1123             :     std::fill(beg, end, nullptr);
    1124             : }
    1125             : 
    1126             : static MOZ_ALWAYS_INLINE void
    1127             : MakeRangeGCSafe(Shape** vec, size_t len)
    1128       38003 : {
    1129       21130 :     MakeRangeGCSafe(vec, vec + len);
    1130             : }
    1131             : 
    1132             : static MOZ_ALWAYS_INLINE void
    1133             : SetValueRangeToUndefined(Value* beg, Value* end)
    1134             : {
    1135       33321 :     for (Value* v = beg; v != end; ++v)
    1136             :         v->setUndefined();
    1137             : }
    1138             : 
    1139             : static MOZ_ALWAYS_INLINE void
    1140             : SetValueRangeToUndefined(Value* vec, size_t len)
    1141             : {
    1142             :     SetValueRangeToUndefined(vec, vec + len);
    1143             : }
    1144             : 
    1145             : static MOZ_ALWAYS_INLINE void
    1146             : SetValueRangeToNull(Value* beg, Value* end)
    1147             : {
    1148             :     for (Value* v = beg; v != end; ++v)
    1149             :         v->setNull();
    1150             : }
    1151             : 
    1152             : static MOZ_ALWAYS_INLINE void
    1153             : SetValueRangeToNull(Value* vec, size_t len)
    1154             : {
    1155             :     SetValueRangeToNull(vec, vec + len);
    1156             : }
    1157             : 
    1158             : extern const JSSecurityCallbacks NullSecurityCallbacks;
    1159             : 
    1160             : // This callback is set by JS::SetProcessLargeAllocationFailureCallback
    1161             : // and may be null. See comment in jsapi.h.
    1162             : extern mozilla::Atomic<JS::LargeAllocationFailureCallback> OnLargeAllocationFailure;
    1163             : 
    1164             : } /* namespace js */
    1165             : 
    1166             : #endif /* vm_Runtime_h */

Generated by: LCOV version 1.13-14-ga5dd952