Backed out changeset 8f976ed899d7 (bug 1847231) for causing bc failures on browser_se...
[gecko.git] / js / src / vm / Runtime.h
blob0c41231a9271f6b2a1c63d4cb0033573d5cf368f
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/. */
7 #ifndef vm_Runtime_h
8 #define vm_Runtime_h
10 #include "mozilla/Assertions.h" // MOZ_ASSERT
11 #include "mozilla/Atomics.h"
12 #include "mozilla/Attributes.h"
13 #include "mozilla/DoublyLinkedList.h"
14 #include "mozilla/LinkedList.h"
15 #include "mozilla/Maybe.h"
16 #include "mozilla/MemoryReporting.h"
17 #include "mozilla/TimeStamp.h"
18 #include "mozilla/XorShift128PlusRNG.h"
20 #include <algorithm>
22 #ifdef JS_HAS_INTL_API
23 # include "builtin/intl/SharedIntlData.h"
24 #endif
25 #include "frontend/ScriptIndex.h"
26 #include "gc/GCRuntime.h"
27 #include "js/AllocationRecording.h"
28 #include "js/BuildId.h" // JS::BuildIdOp
29 #include "js/Context.h"
30 #include "js/experimental/CTypes.h" // JS::CTypesActivityCallback
31 #include "js/friend/StackLimits.h" // js::ReportOverRecursed
32 #include "js/friend/UsageStatistics.h" // JSAccumulateTelemetryDataCallback
33 #include "js/GCVector.h"
34 #include "js/HashTable.h"
35 #include "js/Initialization.h"
36 #include "js/MemoryCallbacks.h"
37 #include "js/Modules.h" // JS::Module{DynamicImport,Metadata,Resolve}Hook
38 #include "js/ScriptPrivate.h"
39 #include "js/shadow/Zone.h"
40 #include "js/ShadowRealmCallbacks.h"
41 #include "js/Stack.h"
42 #include "js/StreamConsumer.h"
43 #include "js/Symbol.h"
44 #include "js/UniquePtr.h"
45 #include "js/Utility.h"
46 #include "js/WaitCallbacks.h"
47 #include "js/Warnings.h" // JS::WarningReporter
48 #include "js/Zone.h"
49 #include "vm/Caches.h" // js::RuntimeCaches
50 #include "vm/CodeCoverage.h"
51 #include "vm/GeckoProfiler.h"
52 #include "vm/JSScript.h"
53 #include "vm/OffThreadPromiseRuntimeState.h" // js::OffThreadPromiseRuntimeState
54 #include "vm/SharedScriptDataTableHolder.h" // js::SharedScriptDataTableHolder
55 #include "vm/Stack.h"
56 #include "wasm/WasmTypeDecls.h"
58 struct JSAtomState;
59 struct JSClass;
60 struct JSErrorInterceptor;
61 struct JSWrapObjectCallbacks;
63 namespace js {
65 class AutoAssertNoContentJS;
66 class Debugger;
67 class EnterDebuggeeNoExecute;
68 class FrontendContext;
69 class PlainObject;
70 class StaticStrings;
72 } // namespace js
74 struct DtoaState;
75 struct JSLocaleCallbacks;
77 #ifdef JS_SIMULATOR_ARM64
78 namespace vixl {
79 class Simulator;
81 #endif
83 namespace js {
85 extern MOZ_COLD void ReportOutOfMemory(JSContext* cx);
86 extern MOZ_COLD void ReportAllocationOverflow(JSContext* maybecx);
87 extern MOZ_COLD void ReportAllocationOverflow(FrontendContext* fc);
88 extern MOZ_COLD void ReportOversizedAllocation(JSContext* cx,
89 const unsigned errorNumber);
91 class Activation;
92 class ActivationIterator;
93 class Shape;
94 class SourceHook;
96 namespace jit {
97 class JitRuntime;
98 class JitActivation;
99 struct PcScriptCache;
100 class CompileRuntime;
102 #ifdef JS_SIMULATOR_ARM64
103 typedef vixl::Simulator Simulator;
104 #elif defined(JS_SIMULATOR)
105 class Simulator;
106 #endif
107 } // namespace jit
109 namespace frontend {
110 struct CompilationInput;
111 struct CompilationStencil;
112 } // namespace frontend
114 // [SMDOC] JS Engine Threading
116 // Threads interacting with a runtime are divided into two categories:
118 // - The main thread is capable of running JS. There's at most one main thread
119 // per runtime.
121 // - Helper threads do not run JS, and are controlled or triggered by activity
122 // on the main thread (or main threads, since all runtimes in a process share
123 // helper threads). Helper threads may have exclusive access to zones created
124 // for them, for parsing and similar tasks, but their activities do not cause
125 // observable changes in script behaviors. Activity on helper threads may be
126 // referred to as happening 'off thread' or on a background thread in some
127 // parts of the VM.
129 } /* namespace js */
131 namespace JS {
132 struct RuntimeSizes;
133 } // namespace JS
135 namespace js {
138 * Storage for well-known symbols. It's a separate struct from the Runtime so
139 * that it can be shared across multiple runtimes. As in JSAtomState, each
140 * field is a smart pointer that's immutable once initialized.
141 * `rt->wellKnownSymbols->iterator` is convertible to Handle<Symbol*>.
143 * Well-known symbols are never GC'd. The description() of each well-known
144 * symbol is a permanent atom.
146 struct WellKnownSymbols {
147 #define DECLARE_SYMBOL(name) ImmutableTenuredPtr<JS::Symbol*> name;
148 JS_FOR_EACH_WELL_KNOWN_SYMBOL(DECLARE_SYMBOL)
149 #undef DECLARE_SYMBOL
151 const ImmutableTenuredPtr<JS::Symbol*>& get(size_t u) const {
152 MOZ_ASSERT(u < JS::WellKnownSymbolLimit);
153 const ImmutableTenuredPtr<JS::Symbol*>* symbols =
154 reinterpret_cast<const ImmutableTenuredPtr<JS::Symbol*>*>(this);
155 return symbols[u];
158 const ImmutableTenuredPtr<JS::Symbol*>& get(JS::SymbolCode code) const {
159 return get(size_t(code));
162 WellKnownSymbols() = default;
163 WellKnownSymbols(const WellKnownSymbols&) = delete;
164 WellKnownSymbols& operator=(const WellKnownSymbols&) = delete;
167 // There are several coarse locks in the enum below. These may be either
168 // per-runtime or per-process. When acquiring more than one of these locks,
169 // the acquisition must be done in the order below to avoid deadlocks.
170 enum RuntimeLock { HelperThreadStateLock, GCLock };
172 inline bool CanUseExtraThreads() {
173 extern bool gCanUseExtraThreads;
174 return gCanUseExtraThreads;
177 void DisableExtraThreads();
179 using ScriptAndCountsVector = GCVector<ScriptAndCounts, 0, SystemAllocPolicy>;
181 class AutoLockScriptData;
183 // Self-hosted lazy functions do not maintain a BaseScript as we can clone from
184 // the copy in the self-hosting zone. To allow these functions to be called by
185 // the JITs, we need a minimal script object. There is one instance per runtime.
186 struct SelfHostedLazyScript {
187 SelfHostedLazyScript() = default;
189 // Pointer to interpreter trampoline. This field is stored at same location as
190 // in BaseScript::jitCodeRaw_.
191 uint8_t* jitCodeRaw_ = nullptr;
193 // Warm-up count of zero. This field is stored at the same offset as
194 // BaseScript::warmUpData_.
195 ScriptWarmUpData warmUpData_ = {};
197 static constexpr size_t offsetOfJitCodeRaw() {
198 return offsetof(SelfHostedLazyScript, jitCodeRaw_);
200 static constexpr size_t offsetOfWarmUpData() {
201 return offsetof(SelfHostedLazyScript, warmUpData_);
205 // An interface for reporting telemetry from within SpiderMonkey. Reporting data
206 // to this interface will forward it to the embedding if a telemetry callback
207 // was registered. It is the embedding's responsibility to store and/or combine
208 // repeated samples for each metric.
209 class Metrics {
210 private:
211 JSRuntime* rt_;
213 public:
214 explicit Metrics(JSRuntime* rt) : rt_(rt) {}
216 // Records a TimeDuration metric. These are converted to integers when being
217 // recorded so choose an appropriate scale. In the future these will be Glean
218 // Timing Distribution metrics.
219 struct TimeDuration_S {
220 using SourceType = mozilla::TimeDuration;
221 static uint32_t convert(SourceType td) { return uint32_t(td.ToSeconds()); }
223 struct TimeDuration_MS {
224 using SourceType = mozilla::TimeDuration;
225 static uint32_t convert(SourceType td) {
226 return uint32_t(td.ToMilliseconds());
229 struct TimeDuration_US {
230 using SourceType = mozilla::TimeDuration;
231 static uint32_t convert(SourceType td) {
232 return uint32_t(td.ToMicroseconds());
236 // Record a metric in bytes. In the future these will be Glean Memory
237 // Distribution metrics.
238 struct MemoryDistribution {
239 using SourceType = size_t;
240 static uint32_t convert(SourceType sz) {
241 return static_cast<uint32_t>(std::min(sz, size_t(UINT32_MAX)));
245 // Record a metric for a quanity of items. This doesn't currently have a Glean
246 // analogue and we avoid using MemoryDistribution directly to avoid confusion
247 // about units.
248 using QuantityDistribution = MemoryDistribution;
250 // Record the distribution of boolean values. In the future this will be a
251 // Glean Rate metric.
252 struct Boolean {
253 using SourceType = bool;
254 static uint32_t convert(SourceType sample) {
255 return static_cast<uint32_t>(sample);
259 // Record the distribution of an enumeration value. This records integer
260 // values so take care not to redefine the value of enum values. In the
261 // future, these should become Glean Labeled Counter metrics.
262 struct Enumeration {
263 using SourceType = unsigned int;
264 static uint32_t convert(SourceType sample) {
265 MOZ_ASSERT(sample <= 100);
266 return static_cast<uint32_t>(sample);
270 // Record a percentage distribution in the range 0 to 100. This takes a double
271 // and converts it to an integer. In the future, this will be a Glean Custom
272 // Distribution unless they add a better match.
273 struct Percentage {
274 using SourceType = double;
275 static uint32_t convert(SourceType sample) {
276 MOZ_ASSERT(sample >= 0.0 && sample <= 100.0);
277 return static_cast<uint32_t>(sample);
281 // Record an unsigned integer.
282 struct Integer {
283 using SourceType = uint32_t;
284 static uint32_t convert(SourceType sample) { return sample; }
287 inline void addTelemetry(JSMetric id, uint32_t sample);
289 #define DECLARE_METRIC_HELPER(NAME, TY) \
290 void NAME(TY::SourceType sample) { \
291 addTelemetry(JSMetric::NAME, TY::convert(sample)); \
293 FOR_EACH_JS_METRIC(DECLARE_METRIC_HELPER)
294 #undef DECLARE_METRIC_HELPER
297 } // namespace js
299 struct JSRuntime {
300 private:
301 friend class js::Activation;
302 friend class js::ActivationIterator;
303 friend class js::jit::JitActivation;
304 friend class js::jit::CompileRuntime;
306 /* Space for interpreter frames. */
307 js::MainThreadData<js::InterpreterStack> interpreterStack_;
309 public:
310 js::InterpreterStack& interpreterStack() { return interpreterStack_.ref(); }
313 * If non-null, another runtime guaranteed to outlive this one and whose
314 * permanent data may be used by this one where possible.
316 JSRuntime* const parentRuntime;
318 bool isMainRuntime() const { return !parentRuntime; }
320 #ifdef DEBUG
321 /* The number of child runtimes that have this runtime as their parent. */
322 mozilla::Atomic<size_t> childRuntimeCount;
324 class AutoUpdateChildRuntimeCount {
325 JSRuntime* parent_;
327 public:
328 explicit AutoUpdateChildRuntimeCount(JSRuntime* parent) : parent_(parent) {
329 if (parent_) {
330 parent_->childRuntimeCount++;
334 ~AutoUpdateChildRuntimeCount() {
335 if (parent_) {
336 parent_->childRuntimeCount--;
341 AutoUpdateChildRuntimeCount updateChildRuntimeCount;
342 #endif
344 private:
345 #ifdef DEBUG
346 js::WriteOnceData<bool> initialized_;
347 #endif
349 // The JSContext* for the runtime's main thread. Immutable after this is set
350 // in JSRuntime::init.
351 JSContext* mainContext_;
353 public:
354 JSContext* mainContextFromAnyThread() const { return mainContext_; }
355 const void* addressOfMainContext() { return &mainContext_; }
356 js::Fprinter parserWatcherFile;
358 inline JSContext* mainContextFromOwnThread();
360 js::Metrics metrics() { return js::Metrics(this); }
363 * The start of the range stored in the profiler sample buffer, as measured
364 * after the most recent sample.
365 * All JitcodeGlobalTable entries referenced from a given sample are
366 * assigned the buffer position of the START of the sample. The buffer
367 * entries that reference the JitcodeGlobalTable entries will only ever be
368 * read from the buffer while the entire sample is still inside the buffer;
369 * if some buffer entries at the start of the sample have left the buffer,
370 * the entire sample will be considered inaccessible.
371 * This means that, once profilerSampleBufferRangeStart_ advances beyond
372 * the sample position that's stored on a JitcodeGlobalTable entry, the
373 * buffer entries that reference this JitcodeGlobalTable entry will be
374 * considered inaccessible, and those JitcodeGlobalTable entry can be
375 * disposed of.
377 mozilla::Atomic<uint64_t, mozilla::ReleaseAcquire>
378 profilerSampleBufferRangeStart_;
380 mozilla::Maybe<uint64_t> profilerSampleBufferRangeStart() {
381 if (beingDestroyed_ || !geckoProfiler().enabled()) {
382 return mozilla::Nothing();
384 uint64_t rangeStart = profilerSampleBufferRangeStart_;
385 return mozilla::Some(rangeStart);
387 void setProfilerSampleBufferRangeStart(uint64_t rangeStart) {
388 profilerSampleBufferRangeStart_ = rangeStart;
391 /* Call this to accumulate telemetry data. May be called from any thread; the
392 * embedder is responsible for locking. */
393 JSAccumulateTelemetryDataCallback telemetryCallback;
395 /* Call this to accumulate use counter data. */
396 js::MainThreadData<JSSetUseCounterCallback> useCounterCallback;
398 public:
399 // Accumulates data for Firefox telemetry.
400 void addTelemetry(JSMetric id, uint32_t sample);
402 void setTelemetryCallback(JSRuntime* rt,
403 JSAccumulateTelemetryDataCallback callback);
405 // Sets the use counter for a specific feature, measuring the presence or
406 // absence of usage of a feature on a specific web page and document which
407 // the passed JSObject belongs to.
408 void setUseCounter(JSObject* obj, JSUseCounter counter);
410 void setUseCounterCallback(JSRuntime* rt, JSSetUseCounterCallback callback);
412 public:
413 js::UnprotectedData<js::OffThreadPromiseRuntimeState> offThreadPromiseState;
414 js::UnprotectedData<JS::ConsumeStreamCallback> consumeStreamCallback;
415 js::UnprotectedData<JS::ReportStreamErrorCallback> reportStreamErrorCallback;
417 js::GlobalObject* getIncumbentGlobal(JSContext* cx);
418 bool enqueuePromiseJob(JSContext* cx, js::HandleFunction job,
419 js::HandleObject promise,
420 js::Handle<js::GlobalObject*> incumbentGlobal);
421 void addUnhandledRejectedPromise(JSContext* cx, js::HandleObject promise);
422 void removeUnhandledRejectedPromise(JSContext* cx, js::HandleObject promise);
424 /* Had an out-of-memory error which did not populate an exception. */
425 mozilla::Atomic<bool, mozilla::SequentiallyConsistent> hadOutOfMemory;
428 * Allow relazifying functions in compartments that are active. This is
429 * only used by the relazifyFunctions() testing function.
431 js::MainThreadData<bool> allowRelazificationForTesting;
433 /* Zone destroy callback. */
434 js::MainThreadData<JSDestroyZoneCallback> destroyZoneCallback;
436 /* Compartment destroy callback. */
437 js::MainThreadData<JSDestroyCompartmentCallback> destroyCompartmentCallback;
439 /* Compartment memory reporting callback. */
440 js::MainThreadData<JSSizeOfIncludingThisCompartmentCallback>
441 sizeOfIncludingThisCompartmentCallback;
443 /* Callback for creating ubi::Nodes representing DOM node objects. Set by
444 * JS::ubi::SetConstructUbiNodeForDOMObjectCallback. Refer to
445 * js/public/UbiNode.h.
447 void (*constructUbiNodeForDOMObjectCallback)(void*, JSObject*) = nullptr;
449 /* Realm destroy callback. */
450 js::MainThreadData<JS::DestroyRealmCallback> destroyRealmCallback;
452 /* Call this to get the name of a realm. */
453 js::MainThreadData<JS::RealmNameCallback> realmNameCallback;
455 js::MainThreadData<mozilla::UniquePtr<js::SourceHook>> sourceHook;
457 js::MainThreadData<const JSSecurityCallbacks*> securityCallbacks;
458 js::MainThreadData<const js::DOMCallbacks*> DOMcallbacks;
459 js::MainThreadData<JSDestroyPrincipalsOp> destroyPrincipals;
460 js::MainThreadData<JSReadPrincipalsOp> readPrincipals;
462 js::MainThreadData<JS::EnsureCanAddPrivateElementOp> canAddPrivateElement;
464 /* Optional warning reporter. */
465 js::MainThreadData<JS::WarningReporter> warningReporter;
467 // Lazy self-hosted functions use a shared SelfHostedLazyScript instance
468 // instead instead of a BaseScript. This contains the minimal pointers to
469 // trampolines for the scripts to support direct jitCodeRaw calls.
470 js::UnprotectedData<js::SelfHostedLazyScript> selfHostedLazyScript;
472 private:
473 // The self-hosted JS code is compiled as a Stencil which is then attached to
474 // the Runtime. This is used to instantiate functions into realms on demand.
475 js::WriteOnceData<js::frontend::CompilationInput*> selfHostStencilInput_;
476 js::WriteOnceData<js::frontend::CompilationStencil*> selfHostStencil_;
478 public:
479 // The self-hosted stencil is immutable once attached to the runtime, so
480 // worker runtimes directly use the stencil on the parent runtime.
481 js::frontend::CompilationInput& selfHostStencilInput() {
482 MOZ_ASSERT(hasSelfHostStencil());
483 return *selfHostStencilInput_.ref();
485 js::frontend::CompilationStencil& selfHostStencil() {
486 MOZ_ASSERT(hasSelfHostStencil());
487 return *selfHostStencil_.ref();
489 bool hasSelfHostStencil() const { return bool(selfHostStencil_.ref()); }
491 // A mapping from the name of self-hosted function to a ScriptIndex range of
492 // the function and inner-functions within the self-hosted stencil.
493 js::MainThreadData<
494 JS::GCHashMap<js::PreBarriered<JSAtom*>, js::frontend::ScriptIndexRange,
495 js::DefaultHasher<JSAtom*>, js::SystemAllocPolicy>>
496 selfHostScriptMap;
498 private:
499 /* Gecko profiling metadata */
500 js::UnprotectedData<js::GeckoProfilerRuntime> geckoProfiler_;
502 public:
503 js::GeckoProfilerRuntime& geckoProfiler() { return geckoProfiler_.ref(); }
505 // Heap GC roots for PersistentRooted pointers.
506 js::MainThreadData<
507 mozilla::EnumeratedArray<JS::RootKind, JS::RootKind::Limit,
508 mozilla::LinkedList<js::PersistentRootedBase>>>
509 heapRoots;
511 void tracePersistentRoots(JSTracer* trc);
512 void finishPersistentRoots();
514 void finishRoots();
516 private:
517 js::UnprotectedData<const JSPrincipals*> trustedPrincipals_;
519 public:
520 void setTrustedPrincipals(const JSPrincipals* p) { trustedPrincipals_ = p; }
521 const JSPrincipals* trustedPrincipals() const { return trustedPrincipals_; }
523 js::MainThreadData<const JSWrapObjectCallbacks*> wrapObjectCallbacks;
524 js::MainThreadData<js::PreserveWrapperCallback> preserveWrapperCallback;
525 js::MainThreadData<js::HasReleasedWrapperCallback> hasReleasedWrapperCallback;
527 js::MainThreadData<js::ScriptEnvironmentPreparer*> scriptEnvironmentPreparer;
529 js::MainThreadData<JS::CTypesActivityCallback> ctypesActivityCallback;
531 private:
532 js::WriteOnceData<const JSClass*> windowProxyClass_;
534 public:
535 const JSClass* maybeWindowProxyClass() const { return windowProxyClass_; }
536 void setWindowProxyClass(const JSClass* clasp) { windowProxyClass_ = clasp; }
538 private:
539 // List of non-ephemeron weak containers to sweep during
540 // beginSweepingSweepGroup.
541 js::MainThreadData<mozilla::LinkedList<JS::detail::WeakCacheBase>>
542 weakCaches_;
544 public:
545 mozilla::LinkedList<JS::detail::WeakCacheBase>& weakCaches() {
546 return weakCaches_.ref();
548 void registerWeakCache(JS::detail::WeakCacheBase* cachep) {
549 weakCaches().insertBack(cachep);
552 template <typename T>
553 struct GlobalObjectWatchersLinkAccess {
554 static mozilla::DoublyLinkedListElement<T>& Get(T* aThis) {
555 return aThis->onNewGlobalObjectWatchersLink;
559 template <typename T>
560 struct GarbageCollectionWatchersLinkAccess {
561 static mozilla::DoublyLinkedListElement<T>& Get(T* aThis) {
562 return aThis->onGarbageCollectionWatchersLink;
566 using OnNewGlobalWatchersList =
567 mozilla::DoublyLinkedList<js::Debugger,
568 GlobalObjectWatchersLinkAccess<js::Debugger>>;
569 using OnGarbageCollectionWatchersList = mozilla::DoublyLinkedList<
570 js::Debugger, GarbageCollectionWatchersLinkAccess<js::Debugger>>;
572 private:
574 * List of all enabled Debuggers that have onNewGlobalObject handler
575 * methods established.
577 js::MainThreadData<OnNewGlobalWatchersList> onNewGlobalObjectWatchers_;
580 * List of all enabled Debuggers that have onGarbageCollection handler
581 * methods established.
583 js::MainThreadData<OnGarbageCollectionWatchersList>
584 onGarbageCollectionWatchers_;
586 public:
587 OnNewGlobalWatchersList& onNewGlobalObjectWatchers() {
588 return onNewGlobalObjectWatchers_.ref();
591 OnGarbageCollectionWatchersList& onGarbageCollectionWatchers() {
592 return onGarbageCollectionWatchers_.ref();
595 private:
596 /* Linked list of all Debugger objects in the runtime. */
597 js::MainThreadData<mozilla::LinkedList<js::Debugger>> debuggerList_;
599 public:
600 mozilla::LinkedList<js::Debugger>& debuggerList() {
601 return debuggerList_.ref();
604 public:
605 JS::HeapState heapState() const { return gc.heapState(); }
607 // How many realms there are across all zones. This number includes
608 // off-thread context realms, so it isn't necessarily equal to the
609 // number of realms visited by RealmsIter.
610 js::MainThreadData<size_t> numRealms;
612 // The Gecko Profiler may want to sample the allocations happening across the
613 // browser. This callback can be registered to record the allocation.
614 js::MainThreadData<JS::RecordAllocationsCallback> recordAllocationCallback;
615 js::MainThreadData<double> allocationSamplingProbability;
617 private:
618 // Number of debuggee realms in the runtime.
619 js::MainThreadData<size_t> numDebuggeeRealms_;
621 // Number of debuggee realms in the runtime observing code coverage.
622 js::MainThreadData<size_t> numDebuggeeRealmsObservingCoverage_;
624 public:
625 void incrementNumDebuggeeRealms();
626 void decrementNumDebuggeeRealms();
628 size_t numDebuggeeRealms() const { return numDebuggeeRealms_; }
630 void incrementNumDebuggeeRealmsObservingCoverage();
631 void decrementNumDebuggeeRealmsObservingCoverage();
633 void startRecordingAllocations(double probability,
634 JS::RecordAllocationsCallback callback);
635 void stopRecordingAllocations();
636 void ensureRealmIsRecordingAllocations(JS::Handle<js::GlobalObject*> global);
638 /* Locale-specific callbacks for string conversion. */
639 js::MainThreadData<const JSLocaleCallbacks*> localeCallbacks;
641 /* Default locale for Internationalization API */
642 js::MainThreadData<js::UniqueChars> defaultLocale;
644 /* If true, new scripts must be created with PC counter information. */
645 js::MainThreadOrIonCompileData<bool> profilingScripts;
647 /* Strong references on scripts held for PCCount profiling API. */
648 js::MainThreadData<JS::PersistentRooted<js::ScriptAndCountsVector>*>
649 scriptAndCountsVector;
651 using RootedPlainObjVec = JS::PersistentRooted<
652 JS::GCVector<js::PlainObject*, 0, js::SystemAllocPolicy>>;
653 js::MainThreadData<js::UniquePtr<RootedPlainObjVec>> watchtowerTestingLog;
655 private:
656 /* Code coverage output. */
657 js::UnprotectedData<js::coverage::LCovRuntime> lcovOutput_;
659 public:
660 js::coverage::LCovRuntime& lcovOutput() { return lcovOutput_.ref(); }
662 private:
663 js::UnprotectedData<js::jit::JitRuntime*> jitRuntime_;
665 public:
666 mozilla::Maybe<js::frontend::ScriptIndexRange> getSelfHostedScriptIndexRange(
667 js::PropertyName* name);
669 [[nodiscard]] bool createJitRuntime(JSContext* cx);
670 js::jit::JitRuntime* jitRuntime() const { return jitRuntime_.ref(); }
671 bool hasJitRuntime() const { return !!jitRuntime_; }
673 private:
674 // Used to generate random keys for hash tables.
675 mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG> randomKeyGenerator_;
676 mozilla::non_crypto::XorShift128PlusRNG& randomKeyGenerator();
678 // Used to generate random hash codes for symbols.
679 mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG>
680 randomHashCodeGenerator_;
682 public:
683 mozilla::HashCodeScrambler randomHashCodeScrambler();
684 mozilla::non_crypto::XorShift128PlusRNG forkRandomKeyGenerator();
686 js::HashNumber randomHashCode();
688 //-------------------------------------------------------------------------
689 // Self-hosting support
690 //-------------------------------------------------------------------------
692 bool hasInitializedSelfHosting() const { return hasSelfHostStencil(); }
694 bool initSelfHostingStencil(JSContext* cx, JS::SelfHostedCache xdrCache,
695 JS::SelfHostedWriter xdrWriter);
696 bool initSelfHostingFromStencil(JSContext* cx);
697 void finishSelfHosting();
698 void traceSelfHostingStencil(JSTracer* trc);
699 js::GeneratorKind getSelfHostedFunctionGeneratorKind(js::PropertyName* name);
700 bool delazifySelfHostedFunction(JSContext* cx,
701 js::Handle<js::PropertyName*> name,
702 js::Handle<JSFunction*> targetFun);
703 bool getSelfHostedValue(JSContext* cx, js::Handle<js::PropertyName*> name,
704 js::MutableHandleValue vp);
705 void assertSelfHostedFunctionHasCanonicalName(
706 JS::Handle<js::PropertyName*> name);
708 private:
709 void setSelfHostingStencil(
710 JS::MutableHandle<js::UniquePtr<js::frontend::CompilationInput>> input,
711 RefPtr<js::frontend::CompilationStencil>&& stencil);
713 //-------------------------------------------------------------------------
714 // Locale information
715 //-------------------------------------------------------------------------
717 public:
719 * Set the default locale for the ECMAScript Internationalization API
720 * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat).
721 * Note that the Internationalization API encourages clients to
722 * specify their own locales.
723 * The locale string remains owned by the caller.
725 bool setDefaultLocale(const char* locale);
727 /* Reset the default locale to OS defaults. */
728 void resetDefaultLocale();
730 /* Gets current default locale. String remains owned by context. */
731 const char* getDefaultLocale();
733 /* Garbage collector state. */
734 js::gc::GCRuntime gc;
736 /* Garbage collector state has been successfully initialized. */
738 bool hasZealMode(js::gc::ZealMode mode) { return gc.hasZealMode(mode); }
740 void lockGC() { gc.lockGC(); }
742 void unlockGC() { gc.unlockGC(); }
744 js::WriteOnceData<js::PropertyName*> emptyString;
746 public:
747 JS::GCContext* gcContext() { return &gc.mainThreadContext.ref(); }
749 #if !JS_HAS_INTL_API
750 /* Number localization, used by jsnum.cpp. */
751 js::WriteOnceData<const char*> thousandsSeparator;
752 js::WriteOnceData<const char*> decimalSeparator;
753 js::WriteOnceData<const char*> numGrouping;
754 #endif
756 private:
757 js::WriteOnceData<bool> beingDestroyed_;
759 public:
760 bool isBeingDestroyed() const { return beingDestroyed_; }
762 private:
763 bool allowContentJS_;
765 public:
766 bool allowContentJS() const { return allowContentJS_; }
768 friend class js::AutoAssertNoContentJS;
770 private:
771 // Table of all atoms other than those in permanentAtoms and staticStrings.
772 js::WriteOnceData<js::AtomsTable*> atoms_;
774 // Set of all live symbols produced by Symbol.for(). All such symbols are
775 // allocated in the atoms zone. Reading or writing the symbol registry
776 // can only be done from the main thread.
777 js::MainThreadOrGCTaskData<js::SymbolRegistry> symbolRegistry_;
779 js::WriteOnceData<js::FrozenAtomSet*> permanentAtoms_;
781 public:
782 bool initializeAtoms(JSContext* cx);
783 void finishAtoms();
784 bool atomsAreFinished() const { return !atoms_; }
786 js::AtomsTable* atomsForSweeping() {
787 MOZ_ASSERT(JS::RuntimeHeapIsCollecting());
788 return atoms_;
791 js::AtomsTable& atoms() {
792 MOZ_ASSERT(atoms_);
793 return *atoms_;
796 JS::Zone* atomsZone() {
797 MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(this));
798 return unsafeAtomsZone();
800 JS::Zone* unsafeAtomsZone() { return gc.atomsZone(); }
802 #ifdef DEBUG
803 bool isAtomsZone(const JS::Zone* zone) const {
804 return JS::shadow::Zone::from(zone)->isAtomsZone();
806 #endif
808 bool activeGCInAtomsZone();
810 js::SymbolRegistry& symbolRegistry() { return symbolRegistry_.ref(); }
812 // Permanent atoms are fixed during initialization of the runtime and are
813 // not modified or collected until the runtime is destroyed. These may be
814 // shared with another, longer living runtime through |parentRuntime| and
815 // can be freely accessed with no locking necessary.
817 // Permanent atoms pre-allocated for general use.
818 js::WriteOnceData<js::StaticStrings*> staticStrings;
820 // Cached pointers to various permanent property names.
821 js::WriteOnceData<JSAtomState*> commonNames;
823 // All permanent atoms in the runtime, other than those in staticStrings.
824 // Access to this does not require a lock because it is frozen and thus
825 // read-only.
826 const js::FrozenAtomSet* permanentAtoms() const {
827 MOZ_ASSERT(permanentAtomsPopulated());
828 return permanentAtoms_.ref();
831 // The permanent atoms table is populated during initialization.
832 bool permanentAtomsPopulated() const { return permanentAtoms_; }
834 // Cached well-known symbols (ES6 rev 24 6.1.5.1). Like permanent atoms,
835 // these are shared with the parentRuntime, if any.
836 js::WriteOnceData<js::WellKnownSymbols*> wellKnownSymbols;
838 #ifdef JS_HAS_INTL_API
839 /* Shared Intl data for this runtime. */
840 js::MainThreadData<js::intl::SharedIntlData> sharedIntlData;
842 void traceSharedIntlData(JSTracer* trc);
843 #endif
845 private:
846 js::SharedScriptDataTableHolder scriptDataTableHolder_;
848 public:
849 // Returns the runtime's local script data table holder.
850 js::SharedScriptDataTableHolder& scriptDataTableHolder();
852 private:
853 static mozilla::Atomic<size_t> liveRuntimesCount;
855 public:
856 static bool hasLiveRuntimes() { return liveRuntimesCount > 0; }
857 static bool hasSingleLiveRuntime() { return liveRuntimesCount == 1; }
859 explicit JSRuntime(JSRuntime* parentRuntime);
860 ~JSRuntime();
862 // destroyRuntime is used instead of a destructor, to ensure the downcast
863 // to JSContext remains valid. The final GC triggered here depends on this.
864 void destroyRuntime();
866 bool init(JSContext* cx, uint32_t maxbytes);
868 JSRuntime* thisFromCtor() { return this; }
870 private:
871 // Number of live SharedArrayBuffer objects, including those in Wasm shared
872 // memories. uint64_t to avoid any risk of overflow.
873 js::MainThreadData<uint64_t> liveSABs;
875 public:
876 void incSABCount() {
877 MOZ_RELEASE_ASSERT(liveSABs != UINT64_MAX);
878 liveSABs++;
881 void decSABCount() {
882 MOZ_RELEASE_ASSERT(liveSABs > 0);
883 liveSABs--;
886 bool hasLiveSABs() const { return liveSABs > 0; }
888 public:
889 js::MainThreadData<JS::BeforeWaitCallback> beforeWaitCallback;
890 js::MainThreadData<JS::AfterWaitCallback> afterWaitCallback;
892 public:
893 void reportAllocationOverflow() {
894 js::ReportAllocationOverflow(static_cast<JSContext*>(nullptr));
898 * This should be called after system malloc/calloc/realloc returns nullptr
899 * to try to recove some memory or to report an error. For realloc, the
900 * original pointer must be passed as reallocPtr.
902 * The function must be called outside the GC lock.
904 JS_PUBLIC_API void* onOutOfMemory(js::AllocFunction allocator,
905 arena_id_t arena, size_t nbytes,
906 void* reallocPtr = nullptr,
907 JSContext* maybecx = nullptr);
909 /* onOutOfMemory but can call OnLargeAllocationFailure. */
910 JS_PUBLIC_API void* onOutOfMemoryCanGC(js::AllocFunction allocator,
911 arena_id_t arena, size_t nbytes,
912 void* reallocPtr = nullptr);
914 static const unsigned LARGE_ALLOCATION = 25 * 1024 * 1024;
916 void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
917 JS::RuntimeSizes* rtSizes);
919 private:
920 // Settings for how helper threads can be used.
921 mozilla::Atomic<bool, mozilla::SequentiallyConsistent>
922 offthreadIonCompilationEnabled_;
923 mozilla::Atomic<bool, mozilla::SequentiallyConsistent>
924 parallelParsingEnabled_;
926 js::MainThreadData<bool> autoWritableJitCodeActive_;
928 public:
929 // Note: these values may be toggled dynamically (in response to about:config
930 // prefs changing).
931 void setOffthreadIonCompilationEnabled(bool value) {
932 offthreadIonCompilationEnabled_ = value;
934 bool canUseOffthreadIonCompilation() const {
935 return offthreadIonCompilationEnabled_;
937 void setParallelParsingEnabled(bool value) {
938 parallelParsingEnabled_ = value;
940 bool canUseParallelParsing() const { return parallelParsingEnabled_; }
942 void toggleAutoWritableJitCodeActive(bool b) {
943 MOZ_ASSERT(autoWritableJitCodeActive_ != b,
944 "AutoWritableJitCode should not be nested.");
945 autoWritableJitCodeActive_ = b;
948 /* See comment for JS::SetOutOfMemoryCallback in js/MemoryCallbacks.h. */
949 js::MainThreadData<JS::OutOfMemoryCallback> oomCallback;
950 js::MainThreadData<void*> oomCallbackData;
953 * Debugger.Memory functions like takeCensus use this embedding-provided
954 * function to assess the size of malloc'd blocks of memory.
956 js::MainThreadData<mozilla::MallocSizeOf> debuggerMallocSizeOf;
958 /* Last time at which an animation was played for this runtime. */
959 js::MainThreadData<mozilla::TimeStamp> lastAnimationTime;
961 private:
962 /* The stack format for the current runtime. Only valid on non-child
963 * runtimes. */
964 mozilla::Atomic<js::StackFormat, mozilla::ReleaseAcquire> stackFormat_;
966 public:
967 js::StackFormat stackFormat() const {
968 const JSRuntime* rt = this;
969 while (rt->parentRuntime) {
970 MOZ_ASSERT(rt->stackFormat_ == js::StackFormat::Default);
971 rt = rt->parentRuntime;
973 MOZ_ASSERT(rt->stackFormat_ != js::StackFormat::Default);
974 return rt->stackFormat_;
976 void setStackFormat(js::StackFormat format) {
977 MOZ_ASSERT(!parentRuntime);
978 MOZ_ASSERT(format != js::StackFormat::Default);
979 stackFormat_ = format;
982 private:
983 // Warning: no data should be accessed in these caches from another thread,
984 // but Ion needs to be able to access addresses inside here, which should be
985 // safe, as the actual cache lookups will be performed on the main thread
986 // through jitted code.
987 js::MainThreadOrIonCompileData<js::RuntimeCaches> caches_;
989 public:
990 js::RuntimeCaches& caches() { return caches_.ref(); }
992 // List of all the live wasm::Instances in the runtime. Equal to the union
993 // of all instances registered in all JS::Realms. Accessed from watchdog
994 // threads for purposes of wasm::InterruptRunningCode().
995 js::ExclusiveData<js::wasm::InstanceVector> wasmInstances;
997 // A counter used when recording the order in which modules had their
998 // AsyncEvaluation field set to true. This is used to order queued
999 // evaluations. This is reset when the last module that was async evaluating
1000 // is finished.
1002 // See https://tc39.es/ecma262/#sec-async-module-execution-fulfilled step 10
1003 // for use.
1004 js::MainThreadData<uint32_t> moduleAsyncEvaluatingPostOrder;
1006 // The implementation-defined abstract operation HostResolveImportedModule.
1007 js::MainThreadData<JS::ModuleResolveHook> moduleResolveHook;
1009 // A hook that implements the abstract operations
1010 // HostGetImportMetaProperties and HostFinalizeImportMeta.
1011 js::MainThreadData<JS::ModuleMetadataHook> moduleMetadataHook;
1013 // A hook that implements the abstract operation
1014 // HostImportModuleDynamically. This is also used to enable/disable dynamic
1015 // module import and can accessed by off-thread parsing.
1016 mozilla::Atomic<JS::ModuleDynamicImportHook> moduleDynamicImportHook;
1018 // The supported module import assertions.
1019 // https://tc39.es/proposal-import-assertions/#sec-hostgetsupportedimportassertions
1020 js::MainThreadData<JS::ImportAssertionVector> supportedImportAssertions;
1022 // Hooks called when script private references are created and destroyed.
1023 js::MainThreadData<JS::ScriptPrivateReferenceHook> scriptPrivateAddRefHook;
1024 js::MainThreadData<JS::ScriptPrivateReferenceHook> scriptPrivateReleaseHook;
1026 void addRefScriptPrivate(const JS::Value& value) {
1027 if (!value.isUndefined() && scriptPrivateAddRefHook) {
1028 scriptPrivateAddRefHook(value);
1032 void releaseScriptPrivate(const JS::Value& value) {
1033 if (!value.isUndefined() && scriptPrivateReleaseHook) {
1034 scriptPrivateReleaseHook(value);
1038 public:
1039 #if defined(NIGHTLY_BUILD)
1040 // Support for informing the embedding of any error thrown.
1041 // This mechanism is designed to let the embedding
1042 // log/report/fail in case certain errors are thrown
1043 // (e.g. SyntaxError, ReferenceError or TypeError
1044 // in critical code).
1045 struct ErrorInterceptionSupport {
1046 ErrorInterceptionSupport() : isExecuting(false), interceptor(nullptr) {}
1048 // true if the error interceptor is currently executing,
1049 // false otherwise. Used to avoid infinite loops.
1050 bool isExecuting;
1052 // if non-null, any call to `setPendingException`
1053 // in this runtime will trigger the call to `interceptor`
1054 JSErrorInterceptor* interceptor;
1056 ErrorInterceptionSupport errorInterception;
1057 #endif // defined(NIGHTLY_BUILD)
1059 public:
1060 JS::GlobalInitializeCallback getShadowRealmInitializeGlobalCallback() {
1061 return shadowRealmInitializeGlobalCallback;
1064 JS::GlobalCreationCallback getShadowRealmGlobalCreationCallback() {
1065 return shadowRealmGlobalCreationCallback;
1068 js::MainThreadData<JS::GlobalInitializeCallback>
1069 shadowRealmInitializeGlobalCallback;
1071 js::MainThreadData<JS::GlobalCreationCallback>
1072 shadowRealmGlobalCreationCallback;
1075 namespace js {
1077 void Metrics::addTelemetry(JSMetric id, uint32_t sample) {
1078 rt_->addTelemetry(id, sample);
1081 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Value* vec, size_t len) {
1082 // Don't PodZero here because JS::Value is non-trivial.
1083 for (size_t i = 0; i < len; i++) {
1084 vec[i].setDouble(+0.0);
1088 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Value* beg, Value* end) {
1089 MakeRangeGCSafe(beg, end - beg);
1092 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(jsid* beg, jsid* end) {
1093 std::fill(beg, end, PropertyKey::Int(0));
1096 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(jsid* vec, size_t len) {
1097 MakeRangeGCSafe(vec, vec + len);
1100 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Shape** beg, Shape** end) {
1101 std::fill(beg, end, nullptr);
1104 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Shape** vec, size_t len) {
1105 MakeRangeGCSafe(vec, vec + len);
1108 static MOZ_ALWAYS_INLINE void SetValueRangeToUndefined(Value* beg, Value* end) {
1109 for (Value* v = beg; v != end; ++v) {
1110 v->setUndefined();
1114 static MOZ_ALWAYS_INLINE void SetValueRangeToUndefined(Value* vec, size_t len) {
1115 SetValueRangeToUndefined(vec, vec + len);
1118 static MOZ_ALWAYS_INLINE void SetValueRangeToNull(Value* beg, Value* end) {
1119 for (Value* v = beg; v != end; ++v) {
1120 v->setNull();
1124 static MOZ_ALWAYS_INLINE void SetValueRangeToNull(Value* vec, size_t len) {
1125 SetValueRangeToNull(vec, vec + len);
1128 extern const JSSecurityCallbacks NullSecurityCallbacks;
1130 // This callback is set by JS::SetProcessLargeAllocationFailureCallback
1131 // and may be null. See comment in jsapi.h.
1132 extern mozilla::Atomic<JS::LargeAllocationFailureCallback>
1133 OnLargeAllocationFailure;
1135 // This callback is set by JS::SetBuildIdOp and may be null. See comment in
1136 // jsapi.h.
1137 extern mozilla::Atomic<JS::BuildIdOp> GetBuildId;
1139 extern JS::FilenameValidationCallback gFilenameValidationCallback;
1141 } /* namespace js */
1143 #endif /* vm_Runtime_h */