Bug 1842773 - Part 32: Allow constructing growable SharedArrayBuffers. r=sfink
[gecko.git] / js / src / vm / Runtime.h
blobf1481411cf1f53864971a539106b750b67ceaeb8
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>
21 #include <utility>
23 #ifdef JS_HAS_INTL_API
24 # include "builtin/intl/SharedIntlData.h"
25 #endif
26 #include "frontend/ScriptIndex.h"
27 #include "gc/GCRuntime.h"
28 #include "js/AllocationRecording.h"
29 #include "js/BuildId.h" // JS::BuildIdOp
30 #include "js/Context.h"
31 #include "js/experimental/CTypes.h" // JS::CTypesActivityCallback
32 #include "js/friend/StackLimits.h" // js::ReportOverRecursed
33 #include "js/friend/UsageStatistics.h" // JSAccumulateTelemetryDataCallback
34 #include "js/GCVector.h"
35 #include "js/HashTable.h"
36 #include "js/Initialization.h"
37 #include "js/MemoryCallbacks.h"
38 #include "js/Modules.h" // JS::Module{DynamicImport,Metadata,Resolve}Hook
39 #include "js/ScriptPrivate.h"
40 #include "js/shadow/Zone.h"
41 #include "js/ShadowRealmCallbacks.h"
42 #include "js/Stack.h"
43 #include "js/StreamConsumer.h"
44 #include "js/Symbol.h"
45 #include "js/UniquePtr.h"
46 #include "js/Utility.h"
47 #include "js/WaitCallbacks.h"
48 #include "js/Warnings.h" // JS::WarningReporter
49 #include "js/Zone.h"
50 #include "vm/Caches.h" // js::RuntimeCaches
51 #include "vm/CodeCoverage.h"
52 #include "vm/GeckoProfiler.h"
53 #include "vm/JSScript.h"
54 #include "vm/OffThreadPromiseRuntimeState.h" // js::OffThreadPromiseRuntimeState
55 #include "vm/SharedScriptDataTableHolder.h" // js::SharedScriptDataTableHolder
56 #include "vm/Stack.h"
57 #include "wasm/WasmTypeDecls.h"
59 struct JSAtomState;
60 struct JSClass;
61 struct JSErrorInterceptor;
62 struct JSWrapObjectCallbacks;
64 namespace js {
66 class AutoAssertNoContentJS;
67 class Debugger;
68 class EnterDebuggeeNoExecute;
69 class FrontendContext;
70 class PlainObject;
71 class StaticStrings;
73 } // namespace js
75 struct DtoaState;
76 struct JSLocaleCallbacks;
78 #ifdef JS_SIMULATOR_ARM64
79 namespace vixl {
80 class Simulator;
82 #endif
84 namespace js {
86 extern MOZ_COLD void ReportOutOfMemory(JSContext* cx);
87 extern MOZ_COLD void ReportAllocationOverflow(JSContext* maybecx);
88 extern MOZ_COLD void ReportAllocationOverflow(FrontendContext* fc);
89 extern MOZ_COLD void ReportOversizedAllocation(JSContext* cx,
90 const unsigned errorNumber);
92 class Activation;
93 class ActivationIterator;
94 class Shape;
95 class SourceHook;
97 namespace jit {
98 class JitRuntime;
99 class JitActivation;
100 struct PcScriptCache;
101 class CompileRuntime;
103 #ifdef JS_SIMULATOR_ARM64
104 typedef vixl::Simulator Simulator;
105 #elif defined(JS_SIMULATOR)
106 class Simulator;
107 #endif
108 } // namespace jit
110 namespace frontend {
111 struct CompilationInput;
112 struct CompilationStencil;
113 } // namespace frontend
115 // [SMDOC] JS Engine Threading
117 // Threads interacting with a runtime are divided into two categories:
119 // - The main thread is capable of running JS. There's at most one main thread
120 // per runtime.
122 // - Helper threads do not run JS, and are controlled or triggered by activity
123 // on the main thread (or main threads, since all runtimes in a process share
124 // helper threads). Helper threads may have exclusive access to zones created
125 // for them, for parsing and similar tasks, but their activities do not cause
126 // observable changes in script behaviors. Activity on helper threads may be
127 // referred to as happening 'off thread' or on a background thread in some
128 // parts of the VM.
130 } /* namespace js */
132 namespace JS {
133 struct RuntimeSizes;
134 } // namespace JS
136 namespace js {
139 * Storage for well-known symbols. It's a separate struct from the Runtime so
140 * that it can be shared across multiple runtimes. As in JSAtomState, each
141 * field is a smart pointer that's immutable once initialized.
142 * `rt->wellKnownSymbols->iterator` is convertible to Handle<Symbol*>.
144 * Well-known symbols are never GC'd. The description() of each well-known
145 * symbol is a permanent atom.
147 struct WellKnownSymbols {
148 #define DECLARE_SYMBOL(name) ImmutableTenuredPtr<JS::Symbol*> name;
149 JS_FOR_EACH_WELL_KNOWN_SYMBOL(DECLARE_SYMBOL)
150 #undef DECLARE_SYMBOL
152 const ImmutableTenuredPtr<JS::Symbol*>& get(size_t u) const {
153 MOZ_ASSERT(u < JS::WellKnownSymbolLimit);
154 const ImmutableTenuredPtr<JS::Symbol*>* symbols =
155 reinterpret_cast<const ImmutableTenuredPtr<JS::Symbol*>*>(this);
156 return symbols[u];
159 const ImmutableTenuredPtr<JS::Symbol*>& get(JS::SymbolCode code) const {
160 return get(size_t(code));
163 WellKnownSymbols() = default;
164 WellKnownSymbols(const WellKnownSymbols&) = delete;
165 WellKnownSymbols& operator=(const WellKnownSymbols&) = delete;
168 // There are several coarse locks in the enum below. These may be either
169 // per-runtime or per-process. When acquiring more than one of these locks,
170 // the acquisition must be done in the order below to avoid deadlocks.
171 enum RuntimeLock { HelperThreadStateLock, GCLock };
173 inline bool CanUseExtraThreads() {
174 extern bool gCanUseExtraThreads;
175 return gCanUseExtraThreads;
178 void DisableExtraThreads();
180 using ScriptAndCountsVector = GCVector<ScriptAndCounts, 0, SystemAllocPolicy>;
182 class AutoLockScriptData;
184 // Self-hosted lazy functions do not maintain a BaseScript as we can clone from
185 // the copy in the self-hosting zone. To allow these functions to be called by
186 // the JITs, we need a minimal script object. There is one instance per runtime.
187 struct SelfHostedLazyScript {
188 SelfHostedLazyScript() = default;
190 // Pointer to interpreter trampoline. This field is stored at same location as
191 // in BaseScript::jitCodeRaw_.
192 uint8_t* jitCodeRaw_ = nullptr;
194 // Warm-up count of zero. This field is stored at the same offset as
195 // BaseScript::warmUpData_.
196 ScriptWarmUpData warmUpData_ = {};
198 static constexpr size_t offsetOfJitCodeRaw() {
199 return offsetof(SelfHostedLazyScript, jitCodeRaw_);
201 static constexpr size_t offsetOfWarmUpData() {
202 return offsetof(SelfHostedLazyScript, warmUpData_);
206 // An interface for reporting telemetry from within SpiderMonkey. Reporting data
207 // to this interface will forward it to the embedding if a telemetry callback
208 // was registered. It is the embedding's responsibility to store and/or combine
209 // repeated samples for each metric.
210 class Metrics {
211 private:
212 JSRuntime* rt_;
214 public:
215 explicit Metrics(JSRuntime* rt) : rt_(rt) {}
217 // Records a TimeDuration metric. These are converted to integers when being
218 // recorded so choose an appropriate scale. In the future these will be Glean
219 // Timing Distribution metrics.
220 struct TimeDuration_S {
221 using SourceType = mozilla::TimeDuration;
222 static uint32_t convert(SourceType td) { return uint32_t(td.ToSeconds()); }
224 struct TimeDuration_MS {
225 using SourceType = mozilla::TimeDuration;
226 static uint32_t convert(SourceType td) {
227 return uint32_t(td.ToMilliseconds());
230 struct TimeDuration_US {
231 using SourceType = mozilla::TimeDuration;
232 static uint32_t convert(SourceType td) {
233 return uint32_t(td.ToMicroseconds());
237 // Record a metric in bytes. In the future these will be Glean Memory
238 // Distribution metrics.
239 struct MemoryDistribution {
240 using SourceType = size_t;
241 static uint32_t convert(SourceType sz) {
242 return static_cast<uint32_t>(std::min(sz, size_t(UINT32_MAX)));
246 // Record a metric for a quanity of items. This doesn't currently have a Glean
247 // analogue and we avoid using MemoryDistribution directly to avoid confusion
248 // about units.
249 using QuantityDistribution = MemoryDistribution;
251 // Record the distribution of boolean values. In the future this will be a
252 // Glean Rate metric.
253 struct Boolean {
254 using SourceType = bool;
255 static uint32_t convert(SourceType sample) {
256 return static_cast<uint32_t>(sample);
260 // Record the distribution of an enumeration value. This records integer
261 // values so take care not to redefine the value of enum values. In the
262 // future, these should become Glean Labeled Counter metrics.
263 struct Enumeration {
264 using SourceType = unsigned int;
265 static uint32_t convert(SourceType sample) {
266 MOZ_ASSERT(sample <= 100);
267 return static_cast<uint32_t>(sample);
271 // Record a percentage distribution in the range 0 to 100. This takes a double
272 // and converts it to an integer. In the future, this will be a Glean Custom
273 // Distribution unless they add a better match.
274 struct Percentage {
275 using SourceType = double;
276 static uint32_t convert(SourceType sample) {
277 MOZ_ASSERT(sample >= 0.0 && sample <= 100.0);
278 return static_cast<uint32_t>(sample);
282 // Record an unsigned integer.
283 struct Integer {
284 using SourceType = uint32_t;
285 static uint32_t convert(SourceType sample) { return sample; }
288 inline void addTelemetry(JSMetric id, uint32_t sample);
290 #define DECLARE_METRIC_HELPER(NAME, TY) \
291 void NAME(TY::SourceType sample) { \
292 addTelemetry(JSMetric::NAME, TY::convert(sample)); \
294 FOR_EACH_JS_METRIC(DECLARE_METRIC_HELPER)
295 #undef DECLARE_METRIC_HELPER
298 } // namespace js
300 struct JSRuntime {
301 private:
302 friend class js::Activation;
303 friend class js::ActivationIterator;
304 friend class js::jit::JitActivation;
305 friend class js::jit::CompileRuntime;
307 /* Space for interpreter frames. */
308 js::MainThreadData<js::InterpreterStack> interpreterStack_;
310 #ifdef ENABLE_PORTABLE_BASELINE_INTERP
311 /* Space for portable baseline interpreter frames. */
312 js::MainThreadData<js::PortableBaselineStack> portableBaselineStack_;
313 #endif
315 public:
316 js::InterpreterStack& interpreterStack() { return interpreterStack_.ref(); }
317 #ifdef ENABLE_PORTABLE_BASELINE_INTERP
318 js::PortableBaselineStack& portableBaselineStack() {
319 return portableBaselineStack_.ref();
321 #endif
324 * If non-null, another runtime guaranteed to outlive this one and whose
325 * permanent data may be used by this one where possible.
327 JSRuntime* const parentRuntime;
329 bool isMainRuntime() const { return !parentRuntime; }
331 #ifdef DEBUG
332 /* The number of child runtimes that have this runtime as their parent. */
333 mozilla::Atomic<size_t> childRuntimeCount;
335 class AutoUpdateChildRuntimeCount {
336 JSRuntime* parent_;
338 public:
339 explicit AutoUpdateChildRuntimeCount(JSRuntime* parent) : parent_(parent) {
340 if (parent_) {
341 parent_->childRuntimeCount++;
345 ~AutoUpdateChildRuntimeCount() {
346 if (parent_) {
347 parent_->childRuntimeCount--;
352 AutoUpdateChildRuntimeCount updateChildRuntimeCount;
353 #endif
355 private:
356 #ifdef DEBUG
357 js::WriteOnceData<bool> initialized_;
358 #endif
360 // The JSContext* for the runtime's main thread. Immutable after this is set
361 // in JSRuntime::init.
362 JSContext* mainContext_;
364 public:
365 JSContext* mainContextFromAnyThread() const { return mainContext_; }
366 const void* addressOfMainContext() { return &mainContext_; }
367 js::Fprinter parserWatcherFile;
369 inline JSContext* mainContextFromOwnThread();
371 js::Metrics metrics() { return js::Metrics(this); }
374 * The start of the range stored in the profiler sample buffer, as measured
375 * after the most recent sample.
376 * All JitcodeGlobalTable entries referenced from a given sample are
377 * assigned the buffer position of the START of the sample. The buffer
378 * entries that reference the JitcodeGlobalTable entries will only ever be
379 * read from the buffer while the entire sample is still inside the buffer;
380 * if some buffer entries at the start of the sample have left the buffer,
381 * the entire sample will be considered inaccessible.
382 * This means that, once profilerSampleBufferRangeStart_ advances beyond
383 * the sample position that's stored on a JitcodeGlobalTable entry, the
384 * buffer entries that reference this JitcodeGlobalTable entry will be
385 * considered inaccessible, and those JitcodeGlobalTable entry can be
386 * disposed of.
388 mozilla::Atomic<uint64_t, mozilla::ReleaseAcquire>
389 profilerSampleBufferRangeStart_;
391 mozilla::Maybe<uint64_t> profilerSampleBufferRangeStart() {
392 if (beingDestroyed_ || !geckoProfiler().enabled()) {
393 return mozilla::Nothing();
395 uint64_t rangeStart = profilerSampleBufferRangeStart_;
396 return mozilla::Some(rangeStart);
398 void setProfilerSampleBufferRangeStart(uint64_t rangeStart) {
399 profilerSampleBufferRangeStart_ = rangeStart;
402 /* Call this to accumulate telemetry data. May be called from any thread; the
403 * embedder is responsible for locking. */
404 JSAccumulateTelemetryDataCallback telemetryCallback;
406 /* Call this to accumulate use counter data. */
407 js::MainThreadData<JSSetUseCounterCallback> useCounterCallback;
409 public:
410 // Accumulates data for Firefox telemetry.
411 void addTelemetry(JSMetric id, uint32_t sample);
413 void setTelemetryCallback(JSRuntime* rt,
414 JSAccumulateTelemetryDataCallback callback);
416 // Sets the use counter for a specific feature, measuring the presence or
417 // absence of usage of a feature on a specific web page and document which
418 // the passed JSObject belongs to.
419 void setUseCounter(JSObject* obj, JSUseCounter counter);
421 void setUseCounterCallback(JSRuntime* rt, JSSetUseCounterCallback callback);
423 public:
424 js::UnprotectedData<js::OffThreadPromiseRuntimeState> offThreadPromiseState;
425 js::UnprotectedData<JS::ConsumeStreamCallback> consumeStreamCallback;
426 js::UnprotectedData<JS::ReportStreamErrorCallback> reportStreamErrorCallback;
428 js::GlobalObject* getIncumbentGlobal(JSContext* cx);
429 bool enqueuePromiseJob(JSContext* cx, js::HandleFunction job,
430 js::HandleObject promise,
431 js::Handle<js::GlobalObject*> incumbentGlobal);
432 void addUnhandledRejectedPromise(JSContext* cx, js::HandleObject promise);
433 void removeUnhandledRejectedPromise(JSContext* cx, js::HandleObject promise);
435 /* Had an out-of-memory error which did not populate an exception. */
436 mozilla::Atomic<bool, mozilla::SequentiallyConsistent> hadOutOfMemory;
439 * Allow relazifying functions in compartments that are active. This is
440 * only used by the relazifyFunctions() testing function.
442 js::MainThreadData<bool> allowRelazificationForTesting;
444 /* Zone destroy callback. */
445 js::MainThreadData<JSDestroyZoneCallback> destroyZoneCallback;
447 /* Compartment destroy callback. */
448 js::MainThreadData<JSDestroyCompartmentCallback> destroyCompartmentCallback;
450 /* Compartment memory reporting callback. */
451 js::MainThreadData<JSSizeOfIncludingThisCompartmentCallback>
452 sizeOfIncludingThisCompartmentCallback;
454 /* Callback for creating ubi::Nodes representing DOM node objects. Set by
455 * JS::ubi::SetConstructUbiNodeForDOMObjectCallback. Refer to
456 * js/public/UbiNode.h.
458 void (*constructUbiNodeForDOMObjectCallback)(void*, JSObject*) = nullptr;
460 /* Realm destroy callback. */
461 js::MainThreadData<JS::DestroyRealmCallback> destroyRealmCallback;
463 /* Call this to get the name of a realm. */
464 js::MainThreadData<JS::RealmNameCallback> realmNameCallback;
466 js::MainThreadData<mozilla::UniquePtr<js::SourceHook>> sourceHook;
468 js::MainThreadData<const JSSecurityCallbacks*> securityCallbacks;
469 js::MainThreadData<const js::DOMCallbacks*> DOMcallbacks;
470 js::MainThreadData<JSDestroyPrincipalsOp> destroyPrincipals;
471 js::MainThreadData<JSReadPrincipalsOp> readPrincipals;
473 js::MainThreadData<JS::EnsureCanAddPrivateElementOp> canAddPrivateElement;
475 /* Optional warning reporter. */
476 js::MainThreadData<JS::WarningReporter> warningReporter;
478 // Lazy self-hosted functions use a shared SelfHostedLazyScript instance
479 // instead instead of a BaseScript. This contains the minimal pointers to
480 // trampolines for the scripts to support direct jitCodeRaw calls.
481 js::UnprotectedData<js::SelfHostedLazyScript> selfHostedLazyScript;
483 private:
484 // The self-hosted JS code is compiled as a Stencil which is then attached to
485 // the Runtime. This is used to instantiate functions into realms on demand.
486 js::WriteOnceData<js::frontend::CompilationInput*> selfHostStencilInput_;
487 js::WriteOnceData<js::frontend::CompilationStencil*> selfHostStencil_;
489 public:
490 // The self-hosted stencil is immutable once attached to the runtime, so
491 // worker runtimes directly use the stencil on the parent runtime.
492 js::frontend::CompilationInput& selfHostStencilInput() {
493 MOZ_ASSERT(hasSelfHostStencil());
494 return *selfHostStencilInput_.ref();
496 js::frontend::CompilationStencil& selfHostStencil() {
497 MOZ_ASSERT(hasSelfHostStencil());
498 return *selfHostStencil_.ref();
500 bool hasSelfHostStencil() const { return bool(selfHostStencil_.ref()); }
502 // A mapping from the name of self-hosted function to a ScriptIndex range of
503 // the function and inner-functions within the self-hosted stencil.
504 js::MainThreadData<
505 JS::GCHashMap<js::PreBarriered<JSAtom*>, js::frontend::ScriptIndexRange,
506 js::DefaultHasher<JSAtom*>, js::SystemAllocPolicy>>
507 selfHostScriptMap;
509 private:
510 /* Gecko profiling metadata */
511 js::UnprotectedData<js::GeckoProfilerRuntime> geckoProfiler_;
513 public:
514 js::GeckoProfilerRuntime& geckoProfiler() { return geckoProfiler_.ref(); }
516 // Heap GC roots for PersistentRooted pointers.
517 js::MainThreadData<
518 mozilla::EnumeratedArray<JS::RootKind, JS::RootKind::Limit,
519 mozilla::LinkedList<js::PersistentRootedBase>>>
520 heapRoots;
522 void tracePersistentRoots(JSTracer* trc);
523 void finishPersistentRoots();
525 void finishRoots();
527 private:
528 js::UnprotectedData<const JSPrincipals*> trustedPrincipals_;
530 public:
531 void setTrustedPrincipals(const JSPrincipals* p) { trustedPrincipals_ = p; }
532 const JSPrincipals* trustedPrincipals() const { return trustedPrincipals_; }
534 js::MainThreadData<const JSWrapObjectCallbacks*> wrapObjectCallbacks;
535 js::MainThreadData<js::PreserveWrapperCallback> preserveWrapperCallback;
536 js::MainThreadData<js::HasReleasedWrapperCallback> hasReleasedWrapperCallback;
538 js::MainThreadData<js::ScriptEnvironmentPreparer*> scriptEnvironmentPreparer;
540 js::MainThreadData<JS::CTypesActivityCallback> ctypesActivityCallback;
542 private:
543 js::WriteOnceData<const JSClass*> windowProxyClass_;
545 public:
546 const JSClass* maybeWindowProxyClass() const { return windowProxyClass_; }
547 void setWindowProxyClass(const JSClass* clasp) { windowProxyClass_ = clasp; }
549 private:
550 // List of non-ephemeron weak containers to sweep during
551 // beginSweepingSweepGroup.
552 js::MainThreadData<mozilla::LinkedList<js::gc::WeakCacheBase>> weakCaches_;
554 public:
555 mozilla::LinkedList<js::gc::WeakCacheBase>& weakCaches() {
556 return weakCaches_.ref();
558 void registerWeakCache(js::gc::WeakCacheBase* cachep) {
559 weakCaches().insertBack(cachep);
562 template <typename T>
563 struct GlobalObjectWatchersLinkAccess {
564 static mozilla::DoublyLinkedListElement<T>& Get(T* aThis) {
565 return aThis->onNewGlobalObjectWatchersLink;
569 template <typename T>
570 struct GarbageCollectionWatchersLinkAccess {
571 static mozilla::DoublyLinkedListElement<T>& Get(T* aThis) {
572 return aThis->onGarbageCollectionWatchersLink;
576 using OnNewGlobalWatchersList =
577 mozilla::DoublyLinkedList<js::Debugger,
578 GlobalObjectWatchersLinkAccess<js::Debugger>>;
579 using OnGarbageCollectionWatchersList = mozilla::DoublyLinkedList<
580 js::Debugger, GarbageCollectionWatchersLinkAccess<js::Debugger>>;
582 private:
584 * List of all enabled Debuggers that have onNewGlobalObject handler
585 * methods established.
587 js::MainThreadData<OnNewGlobalWatchersList> onNewGlobalObjectWatchers_;
590 * List of all enabled Debuggers that have onGarbageCollection handler
591 * methods established.
593 js::MainThreadData<OnGarbageCollectionWatchersList>
594 onGarbageCollectionWatchers_;
596 public:
597 OnNewGlobalWatchersList& onNewGlobalObjectWatchers() {
598 return onNewGlobalObjectWatchers_.ref();
601 OnGarbageCollectionWatchersList& onGarbageCollectionWatchers() {
602 return onGarbageCollectionWatchers_.ref();
605 private:
606 /* Linked list of all Debugger objects in the runtime. */
607 js::MainThreadData<mozilla::LinkedList<js::Debugger>> debuggerList_;
609 public:
610 mozilla::LinkedList<js::Debugger>& debuggerList() {
611 return debuggerList_.ref();
614 public:
615 JS::HeapState heapState() const { return gc.heapState(); }
617 // How many realms there are across all zones. This number includes
618 // off-thread context realms, so it isn't necessarily equal to the
619 // number of realms visited by RealmsIter.
620 js::MainThreadData<size_t> numRealms;
622 // The Gecko Profiler may want to sample the allocations happening across the
623 // browser. This callback can be registered to record the allocation.
624 js::MainThreadData<JS::RecordAllocationsCallback> recordAllocationCallback;
625 js::MainThreadData<double> allocationSamplingProbability;
627 private:
628 // Number of debuggee realms in the runtime.
629 js::MainThreadData<size_t> numDebuggeeRealms_;
631 // Number of debuggee realms in the runtime observing code coverage.
632 js::MainThreadData<size_t> numDebuggeeRealmsObservingCoverage_;
634 public:
635 void incrementNumDebuggeeRealms();
636 void decrementNumDebuggeeRealms();
638 size_t numDebuggeeRealms() const { return numDebuggeeRealms_; }
640 void incrementNumDebuggeeRealmsObservingCoverage();
641 void decrementNumDebuggeeRealmsObservingCoverage();
643 void startRecordingAllocations(double probability,
644 JS::RecordAllocationsCallback callback);
645 void stopRecordingAllocations();
646 void ensureRealmIsRecordingAllocations(JS::Handle<js::GlobalObject*> global);
648 /* Locale-specific callbacks for string conversion. */
649 js::MainThreadData<const JSLocaleCallbacks*> localeCallbacks;
651 /* Default locale for Internationalization API */
652 js::MainThreadData<js::UniqueChars> defaultLocale;
654 /* If true, new scripts must be created with PC counter information. */
655 js::MainThreadOrIonCompileData<bool> profilingScripts;
657 /* Strong references on scripts held for PCCount profiling API. */
658 js::MainThreadData<JS::PersistentRooted<js::ScriptAndCountsVector>*>
659 scriptAndCountsVector;
661 using RootedPlainObjVec = JS::PersistentRooted<
662 JS::GCVector<js::PlainObject*, 0, js::SystemAllocPolicy>>;
663 js::MainThreadData<js::UniquePtr<RootedPlainObjVec>> watchtowerTestingLog;
665 private:
666 /* Code coverage output. */
667 js::UnprotectedData<js::coverage::LCovRuntime> lcovOutput_;
669 /* Functions to call, together with data, when the runtime is being torn down.
671 js::MainThreadData<mozilla::Vector<std::pair<void (*)(void*), void*>, 4>>
672 cleanupClosures;
674 public:
675 js::coverage::LCovRuntime& lcovOutput() { return lcovOutput_.ref(); }
677 /* Register a cleanup function to be called during runtime shutdown. Do not
678 * depend on the ordering of cleanup calls. */
679 bool atExit(void (*function)(void*), void* data) {
680 return cleanupClosures.ref().append(std::pair(function, data));
683 private:
684 js::UnprotectedData<js::jit::JitRuntime*> jitRuntime_;
686 public:
687 mozilla::Maybe<js::frontend::ScriptIndexRange> getSelfHostedScriptIndexRange(
688 js::PropertyName* name);
690 [[nodiscard]] bool createJitRuntime(JSContext* cx);
691 js::jit::JitRuntime* jitRuntime() const { return jitRuntime_.ref(); }
692 bool hasJitRuntime() const { return !!jitRuntime_; }
694 private:
695 // Used to generate random keys for hash tables.
696 mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG> randomKeyGenerator_;
697 mozilla::non_crypto::XorShift128PlusRNG& randomKeyGenerator();
699 // Used to generate random hash codes for symbols.
700 mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG>
701 randomHashCodeGenerator_;
703 public:
704 mozilla::HashCodeScrambler randomHashCodeScrambler();
705 mozilla::non_crypto::XorShift128PlusRNG forkRandomKeyGenerator();
707 js::HashNumber randomHashCode();
709 //-------------------------------------------------------------------------
710 // Self-hosting support
711 //-------------------------------------------------------------------------
713 bool hasInitializedSelfHosting() const { return hasSelfHostStencil(); }
715 bool initSelfHostingStencil(JSContext* cx, JS::SelfHostedCache xdrCache,
716 JS::SelfHostedWriter xdrWriter);
717 bool initSelfHostingFromStencil(JSContext* cx);
718 void finishSelfHosting();
719 void traceSelfHostingStencil(JSTracer* trc);
720 js::GeneratorKind getSelfHostedFunctionGeneratorKind(js::PropertyName* name);
721 bool delazifySelfHostedFunction(JSContext* cx,
722 js::Handle<js::PropertyName*> name,
723 js::Handle<JSFunction*> targetFun);
724 bool getSelfHostedValue(JSContext* cx, js::Handle<js::PropertyName*> name,
725 js::MutableHandleValue vp);
726 void assertSelfHostedFunctionHasCanonicalName(
727 JS::Handle<js::PropertyName*> name);
729 private:
730 void setSelfHostingStencil(
731 JS::MutableHandle<js::UniquePtr<js::frontend::CompilationInput>> input,
732 RefPtr<js::frontend::CompilationStencil>&& stencil);
734 //-------------------------------------------------------------------------
735 // Locale information
736 //-------------------------------------------------------------------------
738 public:
740 * Set the default locale for the ECMAScript Internationalization API
741 * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat).
742 * Note that the Internationalization API encourages clients to
743 * specify their own locales.
744 * The locale string remains owned by the caller.
746 bool setDefaultLocale(const char* locale);
748 /* Reset the default locale to OS defaults. */
749 void resetDefaultLocale();
751 /* Gets current default locale. String remains owned by context. */
752 const char* getDefaultLocale();
754 /* Garbage collector state. */
755 js::gc::GCRuntime gc;
757 /* Garbage collector state has been successfully initialized. */
759 bool hasZealMode(js::gc::ZealMode mode) { return gc.hasZealMode(mode); }
761 void lockGC() { gc.lockGC(); }
763 void unlockGC() { gc.unlockGC(); }
765 js::WriteOnceData<js::PropertyName*> emptyString;
767 public:
768 JS::GCContext* gcContext() { return &gc.mainThreadContext.ref(); }
770 #if !JS_HAS_INTL_API
771 /* Number localization, used by jsnum.cpp. */
772 js::WriteOnceData<const char*> thousandsSeparator;
773 js::WriteOnceData<const char*> decimalSeparator;
774 js::WriteOnceData<const char*> numGrouping;
775 #endif
777 private:
778 js::WriteOnceData<bool> beingDestroyed_;
780 public:
781 bool isBeingDestroyed() const { return beingDestroyed_; }
783 private:
784 bool allowContentJS_;
786 public:
787 bool allowContentJS() const { return allowContentJS_; }
789 friend class js::AutoAssertNoContentJS;
791 private:
792 // Table of all atoms other than those in permanentAtoms and staticStrings.
793 js::WriteOnceData<js::AtomsTable*> atoms_;
795 // Set of all live symbols produced by Symbol.for(). All such symbols are
796 // allocated in the atoms zone. Reading or writing the symbol registry
797 // can only be done from the main thread.
798 js::MainThreadOrGCTaskData<js::SymbolRegistry> symbolRegistry_;
800 js::WriteOnceData<js::FrozenAtomSet*> permanentAtoms_;
802 public:
803 bool initializeAtoms(JSContext* cx);
804 void finishAtoms();
805 bool atomsAreFinished() const { return !atoms_; }
807 js::AtomsTable* atomsForSweeping() {
808 MOZ_ASSERT(JS::RuntimeHeapIsCollecting());
809 return atoms_;
812 js::AtomsTable& atoms() {
813 MOZ_ASSERT(atoms_);
814 return *atoms_;
817 JS::Zone* atomsZone() {
818 MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(this));
819 return unsafeAtomsZone();
821 JS::Zone* unsafeAtomsZone() { return gc.atomsZone(); }
823 #ifdef DEBUG
824 bool isAtomsZone(const JS::Zone* zone) const {
825 return JS::shadow::Zone::from(zone)->isAtomsZone();
827 #endif
829 bool activeGCInAtomsZone();
831 js::SymbolRegistry& symbolRegistry() { return symbolRegistry_.ref(); }
833 // Permanent atoms are fixed during initialization of the runtime and are
834 // not modified or collected until the runtime is destroyed. These may be
835 // shared with another, longer living runtime through |parentRuntime| and
836 // can be freely accessed with no locking necessary.
838 // Permanent atoms pre-allocated for general use.
839 js::WriteOnceData<js::StaticStrings*> staticStrings;
841 // Cached pointers to various permanent property names.
842 js::WriteOnceData<JSAtomState*> commonNames;
844 // All permanent atoms in the runtime, other than those in staticStrings.
845 // Access to this does not require a lock because it is frozen and thus
846 // read-only.
847 const js::FrozenAtomSet* permanentAtoms() const {
848 MOZ_ASSERT(permanentAtomsPopulated());
849 return permanentAtoms_.ref();
852 // The permanent atoms table is populated during initialization.
853 bool permanentAtomsPopulated() const { return permanentAtoms_; }
855 // Cached well-known symbols (ES6 rev 24 6.1.5.1). Like permanent atoms,
856 // these are shared with the parentRuntime, if any.
857 js::WriteOnceData<js::WellKnownSymbols*> wellKnownSymbols;
859 #ifdef JS_HAS_INTL_API
860 /* Shared Intl data for this runtime. */
861 js::MainThreadData<js::intl::SharedIntlData> sharedIntlData;
863 void traceSharedIntlData(JSTracer* trc);
864 #endif
866 private:
867 js::SharedScriptDataTableHolder scriptDataTableHolder_;
869 public:
870 // Returns the runtime's local script data table holder.
871 js::SharedScriptDataTableHolder& scriptDataTableHolder();
873 private:
874 static mozilla::Atomic<size_t> liveRuntimesCount;
876 public:
877 static bool hasLiveRuntimes() { return liveRuntimesCount > 0; }
878 static bool hasSingleLiveRuntime() { return liveRuntimesCount == 1; }
880 explicit JSRuntime(JSRuntime* parentRuntime);
881 ~JSRuntime();
883 // destroyRuntime is used instead of a destructor, to ensure the downcast
884 // to JSContext remains valid. The final GC triggered here depends on this.
885 void destroyRuntime();
887 bool init(JSContext* cx, uint32_t maxbytes);
889 JSRuntime* thisFromCtor() { return this; }
891 private:
892 // Number of live SharedArrayBuffer objects, including those in Wasm shared
893 // memories. uint64_t to avoid any risk of overflow.
894 js::MainThreadData<uint64_t> liveSABs;
896 public:
897 void incSABCount() {
898 MOZ_RELEASE_ASSERT(liveSABs != UINT64_MAX);
899 liveSABs++;
902 void decSABCount() {
903 MOZ_RELEASE_ASSERT(liveSABs > 0);
904 liveSABs--;
907 bool hasLiveSABs() const { return liveSABs > 0; }
909 public:
910 js::MainThreadData<JS::BeforeWaitCallback> beforeWaitCallback;
911 js::MainThreadData<JS::AfterWaitCallback> afterWaitCallback;
913 public:
914 void reportAllocationOverflow() {
915 js::ReportAllocationOverflow(static_cast<JSContext*>(nullptr));
919 * This should be called after system malloc/calloc/realloc returns nullptr
920 * to try to recove some memory or to report an error. For realloc, the
921 * original pointer must be passed as reallocPtr.
923 * The function must be called outside the GC lock.
925 JS_PUBLIC_API void* onOutOfMemory(js::AllocFunction allocator,
926 arena_id_t arena, size_t nbytes,
927 void* reallocPtr = nullptr,
928 JSContext* maybecx = nullptr);
930 /* onOutOfMemory but can call OnLargeAllocationFailure. */
931 JS_PUBLIC_API void* onOutOfMemoryCanGC(js::AllocFunction allocator,
932 arena_id_t arena, size_t nbytes,
933 void* reallocPtr = nullptr);
935 static const unsigned LARGE_ALLOCATION = 25 * 1024 * 1024;
937 void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
938 JS::RuntimeSizes* rtSizes);
940 private:
941 // Settings for how helper threads can be used.
942 mozilla::Atomic<bool, mozilla::SequentiallyConsistent>
943 offthreadIonCompilationEnabled_;
944 mozilla::Atomic<bool, mozilla::SequentiallyConsistent>
945 parallelParsingEnabled_;
947 js::MainThreadData<bool> autoWritableJitCodeActive_;
949 public:
950 // Note: these values may be toggled dynamically (in response to about:config
951 // prefs changing).
952 void setOffthreadIonCompilationEnabled(bool value) {
953 offthreadIonCompilationEnabled_ = value;
955 bool canUseOffthreadIonCompilation() const {
956 return offthreadIonCompilationEnabled_;
958 void setParallelParsingEnabled(bool value) {
959 parallelParsingEnabled_ = value;
961 bool canUseParallelParsing() const { return parallelParsingEnabled_; }
963 void toggleAutoWritableJitCodeActive(bool b) {
964 MOZ_ASSERT(autoWritableJitCodeActive_ != b,
965 "AutoWritableJitCode should not be nested.");
966 autoWritableJitCodeActive_ = b;
969 /* See comment for JS::SetOutOfMemoryCallback in js/MemoryCallbacks.h. */
970 js::MainThreadData<JS::OutOfMemoryCallback> oomCallback;
971 js::MainThreadData<void*> oomCallbackData;
974 * Debugger.Memory functions like takeCensus use this embedding-provided
975 * function to assess the size of malloc'd blocks of memory.
977 js::MainThreadData<mozilla::MallocSizeOf> debuggerMallocSizeOf;
979 /* Last time at which an animation was played for this runtime. */
980 js::MainThreadData<mozilla::TimeStamp> lastAnimationTime;
982 private:
983 /* The stack format for the current runtime. Only valid on non-child
984 * runtimes. */
985 mozilla::Atomic<js::StackFormat, mozilla::ReleaseAcquire> stackFormat_;
987 public:
988 js::StackFormat stackFormat() const {
989 const JSRuntime* rt = this;
990 while (rt->parentRuntime) {
991 MOZ_ASSERT(rt->stackFormat_ == js::StackFormat::Default);
992 rt = rt->parentRuntime;
994 MOZ_ASSERT(rt->stackFormat_ != js::StackFormat::Default);
995 return rt->stackFormat_;
997 void setStackFormat(js::StackFormat format) {
998 MOZ_ASSERT(!parentRuntime);
999 MOZ_ASSERT(format != js::StackFormat::Default);
1000 stackFormat_ = format;
1003 private:
1004 // Warning: no data should be accessed in these caches from another thread,
1005 // but Ion needs to be able to access addresses inside here, which should be
1006 // safe, as the actual cache lookups will be performed on the main thread
1007 // through jitted code.
1008 js::MainThreadOrIonCompileData<js::RuntimeCaches> caches_;
1010 public:
1011 js::RuntimeCaches& caches() { return caches_.ref(); }
1013 // List of all the live wasm::Instances in the runtime. Equal to the union
1014 // of all instances registered in all JS::Realms. Accessed from watchdog
1015 // threads for purposes of wasm::InterruptRunningCode().
1016 js::ExclusiveData<js::wasm::InstanceVector> wasmInstances;
1018 // A counter used when recording the order in which modules had their
1019 // AsyncEvaluation field set to true. This is used to order queued
1020 // evaluations. This is reset when the last module that was async evaluating
1021 // is finished.
1023 // See https://tc39.es/ecma262/#sec-async-module-execution-fulfilled step 10
1024 // for use.
1025 js::MainThreadData<uint32_t> moduleAsyncEvaluatingPostOrder;
1027 // The implementation-defined abstract operation HostResolveImportedModule.
1028 js::MainThreadData<JS::ModuleResolveHook> moduleResolveHook;
1030 // A hook that implements the abstract operations
1031 // HostGetImportMetaProperties and HostFinalizeImportMeta.
1032 js::MainThreadData<JS::ModuleMetadataHook> moduleMetadataHook;
1034 // A hook that implements the abstract operation
1035 // HostImportModuleDynamically. This is also used to enable/disable dynamic
1036 // module import and can accessed by off-thread parsing.
1037 mozilla::Atomic<JS::ModuleDynamicImportHook> moduleDynamicImportHook;
1039 // Hooks called when script private references are created and destroyed.
1040 js::MainThreadData<JS::ScriptPrivateReferenceHook> scriptPrivateAddRefHook;
1041 js::MainThreadData<JS::ScriptPrivateReferenceHook> scriptPrivateReleaseHook;
1043 void addRefScriptPrivate(const JS::Value& value) {
1044 if (!value.isUndefined() && scriptPrivateAddRefHook) {
1045 scriptPrivateAddRefHook(value);
1049 void releaseScriptPrivate(const JS::Value& value) {
1050 if (!value.isUndefined() && scriptPrivateReleaseHook) {
1051 scriptPrivateReleaseHook(value);
1055 public:
1056 #if defined(NIGHTLY_BUILD)
1057 // Support for informing the embedding of any error thrown.
1058 // This mechanism is designed to let the embedding
1059 // log/report/fail in case certain errors are thrown
1060 // (e.g. SyntaxError, ReferenceError or TypeError
1061 // in critical code).
1062 struct ErrorInterceptionSupport {
1063 ErrorInterceptionSupport() : isExecuting(false), interceptor(nullptr) {}
1065 // true if the error interceptor is currently executing,
1066 // false otherwise. Used to avoid infinite loops.
1067 bool isExecuting;
1069 // if non-null, any call to `setPendingException`
1070 // in this runtime will trigger the call to `interceptor`
1071 JSErrorInterceptor* interceptor;
1073 ErrorInterceptionSupport errorInterception;
1074 #endif // defined(NIGHTLY_BUILD)
1076 public:
1077 JS::GlobalInitializeCallback getShadowRealmInitializeGlobalCallback() {
1078 return shadowRealmInitializeGlobalCallback;
1081 JS::GlobalCreationCallback getShadowRealmGlobalCreationCallback() {
1082 return shadowRealmGlobalCreationCallback;
1085 js::MainThreadData<JS::GlobalInitializeCallback>
1086 shadowRealmInitializeGlobalCallback;
1088 js::MainThreadData<JS::GlobalCreationCallback>
1089 shadowRealmGlobalCreationCallback;
1092 namespace js {
1094 void Metrics::addTelemetry(JSMetric id, uint32_t sample) {
1095 rt_->addTelemetry(id, sample);
1098 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Value* vec, size_t len) {
1099 // Don't PodZero here because JS::Value is non-trivial.
1100 for (size_t i = 0; i < len; i++) {
1101 vec[i].setDouble(+0.0);
1105 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Value* beg, Value* end) {
1106 MakeRangeGCSafe(beg, end - beg);
1109 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(jsid* beg, jsid* end) {
1110 std::fill(beg, end, PropertyKey::Int(0));
1113 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(jsid* vec, size_t len) {
1114 MakeRangeGCSafe(vec, vec + len);
1117 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Shape** beg, Shape** end) {
1118 std::fill(beg, end, nullptr);
1121 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Shape** vec, size_t len) {
1122 MakeRangeGCSafe(vec, vec + len);
1125 static MOZ_ALWAYS_INLINE void SetValueRangeToUndefined(Value* beg, Value* end) {
1126 for (Value* v = beg; v != end; ++v) {
1127 v->setUndefined();
1131 static MOZ_ALWAYS_INLINE void SetValueRangeToUndefined(Value* vec, size_t len) {
1132 SetValueRangeToUndefined(vec, vec + len);
1135 static MOZ_ALWAYS_INLINE void SetValueRangeToNull(Value* beg, Value* end) {
1136 for (Value* v = beg; v != end; ++v) {
1137 v->setNull();
1141 static MOZ_ALWAYS_INLINE void SetValueRangeToNull(Value* vec, size_t len) {
1142 SetValueRangeToNull(vec, vec + len);
1145 extern const JSSecurityCallbacks NullSecurityCallbacks;
1147 // This callback is set by JS::SetProcessLargeAllocationFailureCallback
1148 // and may be null. See comment in jsapi.h.
1149 extern mozilla::Atomic<JS::LargeAllocationFailureCallback>
1150 OnLargeAllocationFailure;
1152 // This callback is set by JS::SetBuildIdOp and may be null. See comment in
1153 // jsapi.h.
1154 extern mozilla::Atomic<JS::BuildIdOp> GetBuildId;
1156 extern JS::FilenameValidationCallback gFilenameValidationCallback;
1158 } /* namespace js */
1160 #endif /* vm_Runtime_h */