1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef INCLUDE_V8_ISOLATE_H_
6 #define INCLUDE_V8_ISOLATE_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <memory>
12 #include <utility>
13
14 #include "cppgc/common.h"
15 #include "v8-array-buffer.h" // NOLINT(build/include_directory)
16 #include "v8-callbacks.h" // NOLINT(build/include_directory)
17 #include "v8-data.h" // NOLINT(build/include_directory)
18 #include "v8-debug.h" // NOLINT(build/include_directory)
19 #include "v8-embedder-heap.h" // NOLINT(build/include_directory)
20 #include "v8-function-callback.h" // NOLINT(build/include_directory)
21 #include "v8-internal.h" // NOLINT(build/include_directory)
22 #include "v8-local-handle.h" // NOLINT(build/include_directory)
23 #include "v8-microtask.h" // NOLINT(build/include_directory)
24 #include "v8-persistent-handle.h" // NOLINT(build/include_directory)
25 #include "v8-primitive.h" // NOLINT(build/include_directory)
26 #include "v8-statistics.h" // NOLINT(build/include_directory)
27 #include "v8-unwinder.h" // NOLINT(build/include_directory)
28 #include "v8config.h" // NOLINT(build/include_directory)
29
30 namespace v8 {
31
32 class CppHeap;
33 class HeapProfiler;
34 class MicrotaskQueue;
35 class StartupData;
36 class ScriptOrModule;
37 class SharedArrayBuffer;
38
39 namespace internal {
40 class MicrotaskQueue;
41 class ThreadLocalTop;
42 } // namespace internal
43
44 namespace metrics {
45 class Recorder;
46 } // namespace metrics
47
48 /**
49 * A set of constraints that specifies the limits of the runtime's memory use.
50 * You must set the heap size before initializing the VM - the size cannot be
51 * adjusted after the VM is initialized.
52 *
53 * If you are using threads then you should hold the V8::Locker lock while
54 * setting the stack limit and you must set a non-default stack limit separately
55 * for each thread.
56 *
57 * The arguments for set_max_semi_space_size, set_max_old_space_size,
58 * set_max_executable_size, set_code_range_size specify limits in MB.
59 *
60 * The argument for set_max_semi_space_size_in_kb is in KB.
61 */
62 class V8_EXPORT ResourceConstraints {
63 public:
64 /**
65 * Configures the constraints with reasonable default values based on the
66 * provided heap size limit. The heap size includes both the young and
67 * the old generation.
68 *
69 * \param initial_heap_size_in_bytes The initial heap size or zero.
70 * By default V8 starts with a small heap and dynamically grows it to
71 * match the set of live objects. This may lead to ineffective
72 * garbage collections at startup if the live set is large.
73 * Setting the initial heap size avoids such garbage collections.
74 * Note that this does not affect young generation garbage collections.
75 *
76 * \param maximum_heap_size_in_bytes The hard limit for the heap size.
77 * When the heap size approaches this limit, V8 will perform series of
78 * garbage collections and invoke the NearHeapLimitCallback. If the garbage
79 * collections do not help and the callback does not increase the limit,
80 * then V8 will crash with V8::FatalProcessOutOfMemory.
81 */
82 void ConfigureDefaultsFromHeapSize(size_t initial_heap_size_in_bytes,
83 size_t maximum_heap_size_in_bytes);
84
85 /**
86 * Configures the constraints with reasonable default values based on the
87 * capabilities of the current device the VM is running on.
88 *
89 * \param physical_memory The total amount of physical memory on the current
90 * device, in bytes.
91 * \param virtual_memory_limit The amount of virtual memory on the current
92 * device, in bytes, or zero, if there is no limit.
93 */
94 void ConfigureDefaults(uint64_t physical_memory,
95 uint64_t virtual_memory_limit);
96
97 /**
98 * The address beyond which the VM's stack may not grow.
99 */
stack_limit()100 uint32_t* stack_limit() const { return stack_limit_; }
set_stack_limit(uint32_t * value)101 void set_stack_limit(uint32_t* value) { stack_limit_ = value; }
102
103 /**
104 * The amount of virtual memory reserved for generated code. This is relevant
105 * for 64-bit architectures that rely on code range for calls in code.
106 *
107 * When V8_COMPRESS_POINTERS_IN_SHARED_CAGE is defined, there is a shared
108 * process-wide code range that is lazily initialized. This value is used to
109 * configure that shared code range when the first Isolate is
110 * created. Subsequent Isolates ignore this value.
111 */
code_range_size_in_bytes()112 size_t code_range_size_in_bytes() const { return code_range_size_; }
set_code_range_size_in_bytes(size_t limit)113 void set_code_range_size_in_bytes(size_t limit) { code_range_size_ = limit; }
114
115 /**
116 * The maximum size of the old generation.
117 * When the old generation approaches this limit, V8 will perform series of
118 * garbage collections and invoke the NearHeapLimitCallback.
119 * If the garbage collections do not help and the callback does not
120 * increase the limit, then V8 will crash with V8::FatalProcessOutOfMemory.
121 */
max_old_generation_size_in_bytes()122 size_t max_old_generation_size_in_bytes() const {
123 return max_old_generation_size_;
124 }
set_max_old_generation_size_in_bytes(size_t limit)125 void set_max_old_generation_size_in_bytes(size_t limit) {
126 max_old_generation_size_ = limit;
127 }
128
129 /**
130 * The maximum size of the young generation, which consists of two semi-spaces
131 * and a large object space. This affects frequency of Scavenge garbage
132 * collections and should be typically much smaller that the old generation.
133 */
max_young_generation_size_in_bytes()134 size_t max_young_generation_size_in_bytes() const {
135 return max_young_generation_size_;
136 }
set_max_young_generation_size_in_bytes(size_t limit)137 void set_max_young_generation_size_in_bytes(size_t limit) {
138 max_young_generation_size_ = limit;
139 }
140
initial_old_generation_size_in_bytes()141 size_t initial_old_generation_size_in_bytes() const {
142 return initial_old_generation_size_;
143 }
set_initial_old_generation_size_in_bytes(size_t initial_size)144 void set_initial_old_generation_size_in_bytes(size_t initial_size) {
145 initial_old_generation_size_ = initial_size;
146 }
147
initial_young_generation_size_in_bytes()148 size_t initial_young_generation_size_in_bytes() const {
149 return initial_young_generation_size_;
150 }
set_initial_young_generation_size_in_bytes(size_t initial_size)151 void set_initial_young_generation_size_in_bytes(size_t initial_size) {
152 initial_young_generation_size_ = initial_size;
153 }
154
155 private:
156 static constexpr size_t kMB = 1048576u;
157 size_t code_range_size_ = 0;
158 size_t max_old_generation_size_ = 0;
159 size_t max_young_generation_size_ = 0;
160 size_t initial_old_generation_size_ = 0;
161 size_t initial_young_generation_size_ = 0;
162 uint32_t* stack_limit_ = nullptr;
163 };
164
165 /**
166 * Option flags passed to the SetRAILMode function.
167 * See documentation https://developers.google.com/web/tools/chrome-devtools/
168 * profile/evaluate-performance/rail
169 */
170 enum RAILMode : unsigned {
171 // Response performance mode: In this mode very low virtual machine latency
172 // is provided. V8 will try to avoid JavaScript execution interruptions.
173 // Throughput may be throttled.
174 PERFORMANCE_RESPONSE,
175 // Animation performance mode: In this mode low virtual machine latency is
176 // provided. V8 will try to avoid as many JavaScript execution interruptions
177 // as possible. Throughput may be throttled. This is the default mode.
178 PERFORMANCE_ANIMATION,
179 // Idle performance mode: The embedder is idle. V8 can complete deferred work
180 // in this mode.
181 PERFORMANCE_IDLE,
182 // Load performance mode: In this mode high throughput is provided. V8 may
183 // turn off latency optimizations.
184 PERFORMANCE_LOAD
185 };
186
187 /**
188 * Memory pressure level for the MemoryPressureNotification.
189 * kNone hints V8 that there is no memory pressure.
190 * kModerate hints V8 to speed up incremental garbage collection at the cost of
191 * of higher latency due to garbage collection pauses.
192 * kCritical hints V8 to free memory as soon as possible. Garbage collection
193 * pauses at this level will be large.
194 */
195 enum class MemoryPressureLevel { kNone, kModerate, kCritical };
196
197 /**
198 * Isolate represents an isolated instance of the V8 engine. V8 isolates have
199 * completely separate states. Objects from one isolate must not be used in
200 * other isolates. The embedder can create multiple isolates and use them in
201 * parallel in multiple threads. An isolate can be entered by at most one
202 * thread at any given time. The Locker/Unlocker API must be used to
203 * synchronize.
204 */
205 class V8_EXPORT Isolate {
206 public:
207 /**
208 * Initial configuration parameters for a new Isolate.
209 */
210 struct V8_EXPORT CreateParams {
211 CreateParams();
212 ~CreateParams();
213
214 /**
215 * Allows the host application to provide the address of a function that is
216 * notified each time code is added, moved or removed.
217 */
218 JitCodeEventHandler code_event_handler = nullptr;
219
220 /**
221 * ResourceConstraints to use for the new Isolate.
222 */
223 ResourceConstraints constraints;
224
225 /**
226 * Explicitly specify a startup snapshot blob. The embedder owns the blob.
227 * The embedder *must* ensure that the snapshot is from a trusted source.
228 */
229 StartupData* snapshot_blob = nullptr;
230
231 /**
232 * Enables the host application to provide a mechanism for recording
233 * statistics counters.
234 */
235 CounterLookupCallback counter_lookup_callback = nullptr;
236
237 /**
238 * Enables the host application to provide a mechanism for recording
239 * histograms. The CreateHistogram function returns a
240 * histogram which will later be passed to the AddHistogramSample
241 * function.
242 */
243 CreateHistogramCallback create_histogram_callback = nullptr;
244 AddHistogramSampleCallback add_histogram_sample_callback = nullptr;
245
246 /**
247 * The ArrayBuffer::Allocator to use for allocating and freeing the backing
248 * store of ArrayBuffers.
249 *
250 * If the shared_ptr version is used, the Isolate instance and every
251 * |BackingStore| allocated using this allocator hold a std::shared_ptr
252 * to the allocator, in order to facilitate lifetime
253 * management for the allocator instance.
254 */
255 ArrayBuffer::Allocator* array_buffer_allocator = nullptr;
256 std::shared_ptr<ArrayBuffer::Allocator> array_buffer_allocator_shared;
257
258 /**
259 * Specifies an optional nullptr-terminated array of raw addresses in the
260 * embedder that V8 can match against during serialization and use for
261 * deserialization. This array and its content must stay valid for the
262 * entire lifetime of the isolate.
263 */
264 const intptr_t* external_references = nullptr;
265
266 /**
267 * Whether calling Atomics.wait (a function that may block) is allowed in
268 * this isolate. This can also be configured via SetAllowAtomicsWait.
269 */
270 bool allow_atomics_wait = true;
271
272 /**
273 * Termination is postponed when there is no active SafeForTerminationScope.
274 */
275 bool only_terminate_in_safe_scope = false;
276
277 /**
278 * The following parameters describe the offsets for addressing type info
279 * for wrapped API objects and are used by the fast C API
280 * (for details see v8-fast-api-calls.h).
281 */
282 int embedder_wrapper_type_index = -1;
283 int embedder_wrapper_object_index = -1;
284
285 /**
286 * Callbacks to invoke in case of fatal or OOM errors.
287 */
288 FatalErrorCallback fatal_error_callback = nullptr;
289 OOMErrorCallback oom_error_callback = nullptr;
290
291 /**
292 * The following parameter is experimental and may change significantly.
293 * This is currently for internal testing.
294 */
295 Isolate* experimental_attach_to_shared_isolate = nullptr;
296 };
297
298 /**
299 * Stack-allocated class which sets the isolate for all operations
300 * executed within a local scope.
301 */
302 class V8_EXPORT V8_NODISCARD Scope {
303 public:
Scope(Isolate * isolate)304 explicit Scope(Isolate* isolate) : isolate_(isolate) { isolate->Enter(); }
305
~Scope()306 ~Scope() { isolate_->Exit(); }
307
308 // Prevent copying of Scope objects.
309 Scope(const Scope&) = delete;
310 Scope& operator=(const Scope&) = delete;
311
312 private:
313 Isolate* const isolate_;
314 };
315
316 /**
317 * Assert that no Javascript code is invoked.
318 */
319 class V8_EXPORT V8_NODISCARD DisallowJavascriptExecutionScope {
320 public:
321 enum OnFailure { CRASH_ON_FAILURE, THROW_ON_FAILURE, DUMP_ON_FAILURE };
322
323 DisallowJavascriptExecutionScope(Isolate* isolate, OnFailure on_failure);
324 ~DisallowJavascriptExecutionScope();
325
326 // Prevent copying of Scope objects.
327 DisallowJavascriptExecutionScope(const DisallowJavascriptExecutionScope&) =
328 delete;
329 DisallowJavascriptExecutionScope& operator=(
330 const DisallowJavascriptExecutionScope&) = delete;
331
332 private:
333 OnFailure on_failure_;
334 Isolate* isolate_;
335
336 bool was_execution_allowed_assert_;
337 bool was_execution_allowed_throws_;
338 bool was_execution_allowed_dump_;
339 };
340
341 /**
342 * Introduce exception to DisallowJavascriptExecutionScope.
343 */
344 class V8_EXPORT V8_NODISCARD AllowJavascriptExecutionScope {
345 public:
346 explicit AllowJavascriptExecutionScope(Isolate* isolate);
347 ~AllowJavascriptExecutionScope();
348
349 // Prevent copying of Scope objects.
350 AllowJavascriptExecutionScope(const AllowJavascriptExecutionScope&) =
351 delete;
352 AllowJavascriptExecutionScope& operator=(
353 const AllowJavascriptExecutionScope&) = delete;
354
355 private:
356 Isolate* isolate_;
357 bool was_execution_allowed_assert_;
358 bool was_execution_allowed_throws_;
359 bool was_execution_allowed_dump_;
360 };
361
362 /**
363 * Do not run microtasks while this scope is active, even if microtasks are
364 * automatically executed otherwise.
365 */
366 class V8_EXPORT V8_NODISCARD SuppressMicrotaskExecutionScope {
367 public:
368 explicit SuppressMicrotaskExecutionScope(
369 Isolate* isolate, MicrotaskQueue* microtask_queue = nullptr);
370 ~SuppressMicrotaskExecutionScope();
371
372 // Prevent copying of Scope objects.
373 SuppressMicrotaskExecutionScope(const SuppressMicrotaskExecutionScope&) =
374 delete;
375 SuppressMicrotaskExecutionScope& operator=(
376 const SuppressMicrotaskExecutionScope&) = delete;
377
378 private:
379 internal::Isolate* const isolate_;
380 internal::MicrotaskQueue* const microtask_queue_;
381 internal::Address previous_stack_height_;
382
383 friend class internal::ThreadLocalTop;
384 };
385
386 /**
387 * This scope allows terminations inside direct V8 API calls and forbid them
388 * inside any recursive API calls without explicit SafeForTerminationScope.
389 */
390 class V8_EXPORT V8_NODISCARD SafeForTerminationScope {
391 public:
392 explicit SafeForTerminationScope(v8::Isolate* isolate);
393 ~SafeForTerminationScope();
394
395 // Prevent copying of Scope objects.
396 SafeForTerminationScope(const SafeForTerminationScope&) = delete;
397 SafeForTerminationScope& operator=(const SafeForTerminationScope&) = delete;
398
399 private:
400 internal::Isolate* isolate_;
401 bool prev_value_;
402 };
403
404 /**
405 * Types of garbage collections that can be requested via
406 * RequestGarbageCollectionForTesting.
407 */
408 enum GarbageCollectionType {
409 kFullGarbageCollection,
410 kMinorGarbageCollection
411 };
412
413 /**
414 * Features reported via the SetUseCounterCallback callback. Do not change
415 * assigned numbers of existing items; add new features to the end of this
416 * list.
417 */
418 enum UseCounterFeature {
419 kUseAsm = 0,
420 kBreakIterator = 1,
421 kLegacyConst = 2,
422 kMarkDequeOverflow = 3,
423 kStoreBufferOverflow = 4,
424 kSlotsBufferOverflow = 5,
425 kObjectObserve = 6,
426 kForcedGC = 7,
427 kSloppyMode = 8,
428 kStrictMode = 9,
429 kStrongMode = 10,
430 kRegExpPrototypeStickyGetter = 11,
431 kRegExpPrototypeToString = 12,
432 kRegExpPrototypeUnicodeGetter = 13,
433 kIntlV8Parse = 14,
434 kIntlPattern = 15,
435 kIntlResolved = 16,
436 kPromiseChain = 17,
437 kPromiseAccept = 18,
438 kPromiseDefer = 19,
439 kHtmlCommentInExternalScript = 20,
440 kHtmlComment = 21,
441 kSloppyModeBlockScopedFunctionRedefinition = 22,
442 kForInInitializer = 23,
443 kArrayProtectorDirtied = 24,
444 kArraySpeciesModified = 25,
445 kArrayPrototypeConstructorModified = 26,
446 kArrayInstanceProtoModified = 27,
447 kArrayInstanceConstructorModified = 28,
448 kLegacyFunctionDeclaration = 29,
449 kRegExpPrototypeSourceGetter = 30, // Unused.
450 kRegExpPrototypeOldFlagGetter = 31, // Unused.
451 kDecimalWithLeadingZeroInStrictMode = 32,
452 kLegacyDateParser = 33,
453 kDefineGetterOrSetterWouldThrow = 34,
454 kFunctionConstructorReturnedUndefined = 35,
455 kAssigmentExpressionLHSIsCallInSloppy = 36,
456 kAssigmentExpressionLHSIsCallInStrict = 37,
457 kPromiseConstructorReturnedUndefined = 38,
458 kConstructorNonUndefinedPrimitiveReturn = 39,
459 kLabeledExpressionStatement = 40,
460 kLineOrParagraphSeparatorAsLineTerminator = 41,
461 kIndexAccessor = 42,
462 kErrorCaptureStackTrace = 43,
463 kErrorPrepareStackTrace = 44,
464 kErrorStackTraceLimit = 45,
465 kWebAssemblyInstantiation = 46,
466 kDeoptimizerDisableSpeculation = 47,
467 kArrayPrototypeSortJSArrayModifiedPrototype = 48,
468 kFunctionTokenOffsetTooLongForToString = 49,
469 kWasmSharedMemory = 50,
470 kWasmThreadOpcodes = 51,
471 kAtomicsNotify = 52, // Unused.
472 kAtomicsWake = 53, // Unused.
473 kCollator = 54,
474 kNumberFormat = 55,
475 kDateTimeFormat = 56,
476 kPluralRules = 57,
477 kRelativeTimeFormat = 58,
478 kLocale = 59,
479 kListFormat = 60,
480 kSegmenter = 61,
481 kStringLocaleCompare = 62,
482 kStringToLocaleUpperCase = 63,
483 kStringToLocaleLowerCase = 64,
484 kNumberToLocaleString = 65,
485 kDateToLocaleString = 66,
486 kDateToLocaleDateString = 67,
487 kDateToLocaleTimeString = 68,
488 kAttemptOverrideReadOnlyOnPrototypeSloppy = 69,
489 kAttemptOverrideReadOnlyOnPrototypeStrict = 70,
490 kOptimizedFunctionWithOneShotBytecode = 71, // Unused.
491 kRegExpMatchIsTrueishOnNonJSRegExp = 72,
492 kRegExpMatchIsFalseishOnJSRegExp = 73,
493 kDateGetTimezoneOffset = 74, // Unused.
494 kStringNormalize = 75,
495 kCallSiteAPIGetFunctionSloppyCall = 76,
496 kCallSiteAPIGetThisSloppyCall = 77,
497 kRegExpMatchAllWithNonGlobalRegExp = 78,
498 kRegExpExecCalledOnSlowRegExp = 79,
499 kRegExpReplaceCalledOnSlowRegExp = 80,
500 kDisplayNames = 81,
501 kSharedArrayBufferConstructed = 82,
502 kArrayPrototypeHasElements = 83,
503 kObjectPrototypeHasElements = 84,
504 kNumberFormatStyleUnit = 85,
505 kDateTimeFormatRange = 86,
506 kDateTimeFormatDateTimeStyle = 87,
507 kBreakIteratorTypeWord = 88,
508 kBreakIteratorTypeLine = 89,
509 kInvalidatedArrayBufferDetachingProtector = 90,
510 kInvalidatedArrayConstructorProtector = 91,
511 kInvalidatedArrayIteratorLookupChainProtector = 92,
512 kInvalidatedArraySpeciesLookupChainProtector = 93,
513 kInvalidatedIsConcatSpreadableLookupChainProtector = 94,
514 kInvalidatedMapIteratorLookupChainProtector = 95,
515 kInvalidatedNoElementsProtector = 96,
516 kInvalidatedPromiseHookProtector = 97,
517 kInvalidatedPromiseResolveLookupChainProtector = 98,
518 kInvalidatedPromiseSpeciesLookupChainProtector = 99,
519 kInvalidatedPromiseThenLookupChainProtector = 100,
520 kInvalidatedRegExpSpeciesLookupChainProtector = 101,
521 kInvalidatedSetIteratorLookupChainProtector = 102,
522 kInvalidatedStringIteratorLookupChainProtector = 103,
523 kInvalidatedStringLengthOverflowLookupChainProtector = 104,
524 kInvalidatedTypedArraySpeciesLookupChainProtector = 105,
525 kWasmSimdOpcodes = 106,
526 kVarRedeclaredCatchBinding = 107,
527 kWasmRefTypes = 108,
528 kWasmBulkMemory = 109, // Unused.
529 kWasmMultiValue = 110,
530 kWasmExceptionHandling = 111,
531 kInvalidatedMegaDOMProtector = 112,
532 kFunctionPrototypeArguments = 113,
533 kFunctionPrototypeCaller = 114,
534
535 // If you add new values here, you'll also need to update Chromium's:
536 // web_feature.mojom, use_counter_callback.cc, and enums.xml. V8 changes to
537 // this list need to be landed first, then changes on the Chromium side.
538 kUseCounterFeatureCount // This enum value must be last.
539 };
540
541 enum MessageErrorLevel {
542 kMessageLog = (1 << 0),
543 kMessageDebug = (1 << 1),
544 kMessageInfo = (1 << 2),
545 kMessageError = (1 << 3),
546 kMessageWarning = (1 << 4),
547 kMessageAll = kMessageLog | kMessageDebug | kMessageInfo | kMessageError |
548 kMessageWarning,
549 };
550
551 using UseCounterCallback = void (*)(Isolate* isolate,
552 UseCounterFeature feature);
553
554 /**
555 * Allocates a new isolate but does not initialize it. Does not change the
556 * currently entered isolate.
557 *
558 * Only Isolate::GetData() and Isolate::SetData(), which access the
559 * embedder-controlled parts of the isolate, are allowed to be called on the
560 * uninitialized isolate. To initialize the isolate, call
561 * Isolate::Initialize().
562 *
563 * When an isolate is no longer used its resources should be freed
564 * by calling Dispose(). Using the delete operator is not allowed.
565 *
566 * V8::Initialize() must have run prior to this.
567 */
568 static Isolate* Allocate();
569
570 /**
571 * Initialize an Isolate previously allocated by Isolate::Allocate().
572 */
573 static void Initialize(Isolate* isolate, const CreateParams& params);
574
575 /**
576 * Creates a new isolate. Does not change the currently entered
577 * isolate.
578 *
579 * When an isolate is no longer used its resources should be freed
580 * by calling Dispose(). Using the delete operator is not allowed.
581 *
582 * V8::Initialize() must have run prior to this.
583 */
584 static Isolate* New(const CreateParams& params);
585
586 /**
587 * Returns the entered isolate for the current thread or NULL in
588 * case there is no current isolate.
589 *
590 * This method must not be invoked before V8::Initialize() was invoked.
591 */
592 static Isolate* GetCurrent();
593
594 /**
595 * Returns the entered isolate for the current thread or NULL in
596 * case there is no current isolate.
597 *
598 * No checks are performed by this method.
599 */
600 static Isolate* TryGetCurrent();
601
602 /**
603 * Return true if this isolate is currently active.
604 **/
605 bool IsCurrent() const;
606
607 /**
608 * Clears the set of objects held strongly by the heap. This set of
609 * objects are originally built when a WeakRef is created or
610 * successfully dereferenced.
611 *
612 * This is invoked automatically after microtasks are run. See
613 * MicrotasksPolicy for when microtasks are run.
614 *
615 * This needs to be manually invoked only if the embedder is manually running
616 * microtasks via a custom MicrotaskQueue class's PerformCheckpoint. In that
617 * case, it is the embedder's responsibility to make this call at a time which
618 * does not interrupt synchronous ECMAScript code execution.
619 */
620 void ClearKeptObjects();
621
622 /**
623 * Custom callback used by embedders to help V8 determine if it should abort
624 * when it throws and no internal handler is predicted to catch the
625 * exception. If --abort-on-uncaught-exception is used on the command line,
626 * then V8 will abort if either:
627 * - no custom callback is set.
628 * - the custom callback set returns true.
629 * Otherwise, the custom callback will not be called and V8 will not abort.
630 */
631 using AbortOnUncaughtExceptionCallback = bool (*)(Isolate*);
632 void SetAbortOnUncaughtExceptionCallback(
633 AbortOnUncaughtExceptionCallback callback);
634
635 /**
636 * This specifies the callback called by the upcoming dynamic
637 * import() language feature to load modules.
638 */
639 V8_DEPRECATED("Use HostImportModuleDynamicallyCallback")
640 void SetHostImportModuleDynamicallyCallback(
641 HostImportModuleDynamicallyWithImportAssertionsCallback callback);
642 void SetHostImportModuleDynamicallyCallback(
643 HostImportModuleDynamicallyCallback callback);
644
645 /**
646 * This specifies the callback called by the upcoming import.meta
647 * language feature to retrieve host-defined meta data for a module.
648 */
649 void SetHostInitializeImportMetaObjectCallback(
650 HostInitializeImportMetaObjectCallback callback);
651
652 /**
653 * This specifies the callback called by the upcoming ShadowRealm
654 * construction language feature to retrieve host created globals.
655 */
656 void SetHostCreateShadowRealmContextCallback(
657 HostCreateShadowRealmContextCallback callback);
658
659 /**
660 * This specifies the callback called when the stack property of Error
661 * is accessed.
662 */
663 void SetPrepareStackTraceCallback(PrepareStackTraceCallback callback);
664
665 /**
666 * Optional notification that the system is running low on memory.
667 * V8 uses these notifications to guide heuristics.
668 * It is allowed to call this function from another thread while
669 * the isolate is executing long running JavaScript code.
670 */
671 void MemoryPressureNotification(MemoryPressureLevel level);
672
673 /**
674 * Drop non-essential caches. Should only be called from testing code.
675 * The method can potentially block for a long time and does not necessarily
676 * trigger GC.
677 */
678 void ClearCachesForTesting();
679
680 /**
681 * Methods below this point require holding a lock (using Locker) in
682 * a multi-threaded environment.
683 */
684
685 /**
686 * Sets this isolate as the entered one for the current thread.
687 * Saves the previously entered one (if any), so that it can be
688 * restored when exiting. Re-entering an isolate is allowed.
689 */
690 void Enter();
691
692 /**
693 * Exits this isolate by restoring the previously entered one in the
694 * current thread. The isolate may still stay the same, if it was
695 * entered more than once.
696 *
697 * Requires: this == Isolate::GetCurrent().
698 */
699 void Exit();
700
701 /**
702 * Disposes the isolate. The isolate must not be entered by any
703 * thread to be disposable.
704 */
705 void Dispose();
706
707 /**
708 * Dumps activated low-level V8 internal stats. This can be used instead
709 * of performing a full isolate disposal.
710 */
711 void DumpAndResetStats();
712
713 /**
714 * Discards all V8 thread-specific data for the Isolate. Should be used
715 * if a thread is terminating and it has used an Isolate that will outlive
716 * the thread -- all thread-specific data for an Isolate is discarded when
717 * an Isolate is disposed so this call is pointless if an Isolate is about
718 * to be Disposed.
719 */
720 void DiscardThreadSpecificMetadata();
721
722 /**
723 * Associate embedder-specific data with the isolate. |slot| has to be
724 * between 0 and GetNumberOfDataSlots() - 1.
725 */
726 V8_INLINE void SetData(uint32_t slot, void* data);
727
728 /**
729 * Retrieve embedder-specific data from the isolate.
730 * Returns NULL if SetData has never been called for the given |slot|.
731 */
732 V8_INLINE void* GetData(uint32_t slot);
733
734 /**
735 * Returns the maximum number of available embedder data slots. Valid slots
736 * are in the range of 0 - GetNumberOfDataSlots() - 1.
737 */
738 V8_INLINE static uint32_t GetNumberOfDataSlots();
739
740 /**
741 * Return data that was previously attached to the isolate snapshot via
742 * SnapshotCreator, and removes the reference to it.
743 * Repeated call with the same index returns an empty MaybeLocal.
744 */
745 template <class T>
746 V8_INLINE MaybeLocal<T> GetDataFromSnapshotOnce(size_t index);
747
748 /**
749 * Get statistics about the heap memory usage.
750 */
751 void GetHeapStatistics(HeapStatistics* heap_statistics);
752
753 /**
754 * Returns the number of spaces in the heap.
755 */
756 size_t NumberOfHeapSpaces();
757
758 /**
759 * Get the memory usage of a space in the heap.
760 *
761 * \param space_statistics The HeapSpaceStatistics object to fill in
762 * statistics.
763 * \param index The index of the space to get statistics from, which ranges
764 * from 0 to NumberOfHeapSpaces() - 1.
765 * \returns true on success.
766 */
767 bool GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
768 size_t index);
769
770 /**
771 * Returns the number of types of objects tracked in the heap at GC.
772 */
773 size_t NumberOfTrackedHeapObjectTypes();
774
775 /**
776 * Get statistics about objects in the heap.
777 *
778 * \param object_statistics The HeapObjectStatistics object to fill in
779 * statistics of objects of given type, which were live in the previous GC.
780 * \param type_index The index of the type of object to fill details about,
781 * which ranges from 0 to NumberOfTrackedHeapObjectTypes() - 1.
782 * \returns true on success.
783 */
784 bool GetHeapObjectStatisticsAtLastGC(HeapObjectStatistics* object_statistics,
785 size_t type_index);
786
787 /**
788 * Get statistics about code and its metadata in the heap.
789 *
790 * \param object_statistics The HeapCodeStatistics object to fill in
791 * statistics of code, bytecode and their metadata.
792 * \returns true on success.
793 */
794 bool GetHeapCodeAndMetadataStatistics(HeapCodeStatistics* object_statistics);
795
796 /**
797 * This API is experimental and may change significantly.
798 *
799 * Enqueues a memory measurement request and invokes the delegate with the
800 * results.
801 *
802 * \param delegate the delegate that defines which contexts to measure and
803 * reports the results.
804 *
805 * \param execution promptness executing the memory measurement.
806 * The kEager value is expected to be used only in tests.
807 */
808 bool MeasureMemory(
809 std::unique_ptr<MeasureMemoryDelegate> delegate,
810 MeasureMemoryExecution execution = MeasureMemoryExecution::kDefault);
811
812 /**
813 * Get a call stack sample from the isolate.
814 * \param state Execution state.
815 * \param frames Caller allocated buffer to store stack frames.
816 * \param frames_limit Maximum number of frames to capture. The buffer must
817 * be large enough to hold the number of frames.
818 * \param sample_info The sample info is filled up by the function
819 * provides number of actual captured stack frames and
820 * the current VM state.
821 * \note GetStackSample should only be called when the JS thread is paused or
822 * interrupted. Otherwise the behavior is undefined.
823 */
824 void GetStackSample(const RegisterState& state, void** frames,
825 size_t frames_limit, SampleInfo* sample_info);
826
827 /**
828 * Adjusts the amount of registered external memory. Used to give V8 an
829 * indication of the amount of externally allocated memory that is kept alive
830 * by JavaScript objects. V8 uses this to decide when to perform global
831 * garbage collections. Registering externally allocated memory will trigger
832 * global garbage collections more often than it would otherwise in an attempt
833 * to garbage collect the JavaScript objects that keep the externally
834 * allocated memory alive.
835 *
836 * \param change_in_bytes the change in externally allocated memory that is
837 * kept alive by JavaScript objects.
838 * \returns the adjusted value.
839 */
840 int64_t AdjustAmountOfExternalAllocatedMemory(int64_t change_in_bytes);
841
842 /**
843 * Returns the number of phantom handles without callbacks that were reset
844 * by the garbage collector since the last call to this function.
845 */
846 size_t NumberOfPhantomHandleResetsSinceLastCall();
847
848 /**
849 * Returns heap profiler for this isolate. Will return NULL until the isolate
850 * is initialized.
851 */
852 HeapProfiler* GetHeapProfiler();
853
854 /**
855 * Tells the VM whether the embedder is idle or not.
856 */
857 void SetIdle(bool is_idle);
858
859 /** Returns the ArrayBuffer::Allocator used in this isolate. */
860 ArrayBuffer::Allocator* GetArrayBufferAllocator();
861
862 /** Returns true if this isolate has a current context. */
863 bool InContext();
864
865 /**
866 * Returns the context of the currently running JavaScript, or the context
867 * on the top of the stack if no JavaScript is running.
868 */
869 Local<Context> GetCurrentContext();
870
871 /**
872 * Returns either the last context entered through V8's C++ API, or the
873 * context of the currently running microtask while processing microtasks.
874 * If a context is entered while executing a microtask, that context is
875 * returned.
876 */
877 Local<Context> GetEnteredOrMicrotaskContext();
878
879 /**
880 * Returns the Context that corresponds to the Incumbent realm in HTML spec.
881 * https://html.spec.whatwg.org/multipage/webappapis.html#incumbent
882 */
883 Local<Context> GetIncumbentContext();
884
885 /**
886 * Schedules a v8::Exception::Error with the given message.
887 * See ThrowException for more details. Templatized to provide compile-time
888 * errors in case of too long strings (see v8::String::NewFromUtf8Literal).
889 */
890 template <int N>
ThrowError(const char (& message)[N])891 Local<Value> ThrowError(const char (&message)[N]) {
892 return ThrowError(String::NewFromUtf8Literal(this, message));
893 }
894 Local<Value> ThrowError(Local<String> message);
895
896 /**
897 * Schedules an exception to be thrown when returning to JavaScript. When an
898 * exception has been scheduled it is illegal to invoke any JavaScript
899 * operation; the caller must return immediately and only after the exception
900 * has been handled does it become legal to invoke JavaScript operations.
901 */
902 Local<Value> ThrowException(Local<Value> exception);
903
904 using GCCallback = void (*)(Isolate* isolate, GCType type,
905 GCCallbackFlags flags);
906 using GCCallbackWithData = void (*)(Isolate* isolate, GCType type,
907 GCCallbackFlags flags, void* data);
908
909 /**
910 * Enables the host application to receive a notification before a
911 * garbage collection. Allocations are allowed in the callback function,
912 * but the callback is not re-entrant: if the allocation inside it will
913 * trigger the garbage collection, the callback won't be called again.
914 * It is possible to specify the GCType filter for your callback. But it is
915 * not possible to register the same callback function two times with
916 * different GCType filters.
917 */
918 void AddGCPrologueCallback(GCCallbackWithData callback, void* data = nullptr,
919 GCType gc_type_filter = kGCTypeAll);
920 void AddGCPrologueCallback(GCCallback callback,
921 GCType gc_type_filter = kGCTypeAll);
922
923 /**
924 * This function removes callback which was installed by
925 * AddGCPrologueCallback function.
926 */
927 void RemoveGCPrologueCallback(GCCallbackWithData, void* data = nullptr);
928 void RemoveGCPrologueCallback(GCCallback callback);
929
930 /**
931 * Sets the embedder heap tracer for the isolate.
932 * SetEmbedderHeapTracer cannot be used simultaneously with AttachCppHeap.
933 */
934 void SetEmbedderHeapTracer(EmbedderHeapTracer* tracer);
935
936 /*
937 * Gets the currently active heap tracer for the isolate that was set with
938 * SetEmbedderHeapTracer.
939 */
940 EmbedderHeapTracer* GetEmbedderHeapTracer();
941
942 /**
943 * Sets an embedder roots handle that V8 should consider when performing
944 * non-unified heap garbage collections.
945 *
946 * Using only EmbedderHeapTracer automatically sets up a default handler.
947 * The intended use case is for setting a custom handler after invoking
948 * `AttachCppHeap()`.
949 *
950 * V8 does not take ownership of the handler.
951 */
952 void SetEmbedderRootsHandler(EmbedderRootsHandler* handler);
953
954 /**
955 * Attaches a managed C++ heap as an extension to the JavaScript heap. The
956 * embedder maintains ownership of the CppHeap. At most one C++ heap can be
957 * attached to V8.
958 * AttachCppHeap cannot be used simultaneously with SetEmbedderHeapTracer.
959 *
960 * This is an experimental feature and may still change significantly.
961 */
962 void AttachCppHeap(CppHeap*);
963
964 /**
965 * Detaches a managed C++ heap if one was attached using `AttachCppHeap()`.
966 *
967 * This is an experimental feature and may still change significantly.
968 */
969 void DetachCppHeap();
970
971 /**
972 * This is an experimental feature and may still change significantly.
973
974 * \returns the C++ heap managed by V8. Only available if such a heap has been
975 * attached using `AttachCppHeap()`.
976 */
977 CppHeap* GetCppHeap() const;
978
979 /**
980 * Use for |AtomicsWaitCallback| to indicate the type of event it receives.
981 */
982 enum class AtomicsWaitEvent {
983 /** Indicates that this call is happening before waiting. */
984 kStartWait,
985 /** `Atomics.wait()` finished because of an `Atomics.wake()` call. */
986 kWokenUp,
987 /** `Atomics.wait()` finished because it timed out. */
988 kTimedOut,
989 /** `Atomics.wait()` was interrupted through |TerminateExecution()|. */
990 kTerminatedExecution,
991 /** `Atomics.wait()` was stopped through |AtomicsWaitWakeHandle|. */
992 kAPIStopped,
993 /** `Atomics.wait()` did not wait, as the initial condition was not met. */
994 kNotEqual
995 };
996
997 /**
998 * Passed to |AtomicsWaitCallback| as a means of stopping an ongoing
999 * `Atomics.wait` call.
1000 */
1001 class V8_EXPORT AtomicsWaitWakeHandle {
1002 public:
1003 /**
1004 * Stop this `Atomics.wait()` call and call the |AtomicsWaitCallback|
1005 * with |kAPIStopped|.
1006 *
1007 * This function may be called from another thread. The caller has to ensure
1008 * through proper synchronization that it is not called after
1009 * the finishing |AtomicsWaitCallback|.
1010 *
1011 * Note that the ECMAScript specification does not plan for the possibility
1012 * of wakeups that are neither coming from a timeout or an `Atomics.wake()`
1013 * call, so this may invalidate assumptions made by existing code.
1014 * The embedder may accordingly wish to schedule an exception in the
1015 * finishing |AtomicsWaitCallback|.
1016 */
1017 void Wake();
1018 };
1019
1020 /**
1021 * Embedder callback for `Atomics.wait()` that can be added through
1022 * |SetAtomicsWaitCallback|.
1023 *
1024 * This will be called just before starting to wait with the |event| value
1025 * |kStartWait| and after finishing waiting with one of the other
1026 * values of |AtomicsWaitEvent| inside of an `Atomics.wait()` call.
1027 *
1028 * |array_buffer| will refer to the underlying SharedArrayBuffer,
1029 * |offset_in_bytes| to the location of the waited-on memory address inside
1030 * the SharedArrayBuffer.
1031 *
1032 * |value| and |timeout_in_ms| will be the values passed to
1033 * the `Atomics.wait()` call. If no timeout was used, |timeout_in_ms|
1034 * will be `INFINITY`.
1035 *
1036 * In the |kStartWait| callback, |stop_handle| will be an object that
1037 * is only valid until the corresponding finishing callback and that
1038 * can be used to stop the wait process while it is happening.
1039 *
1040 * This callback may schedule exceptions, *unless* |event| is equal to
1041 * |kTerminatedExecution|.
1042 */
1043 using AtomicsWaitCallback = void (*)(AtomicsWaitEvent event,
1044 Local<SharedArrayBuffer> array_buffer,
1045 size_t offset_in_bytes, int64_t value,
1046 double timeout_in_ms,
1047 AtomicsWaitWakeHandle* stop_handle,
1048 void* data);
1049
1050 /**
1051 * Set a new |AtomicsWaitCallback|. This overrides an earlier
1052 * |AtomicsWaitCallback|, if there was any. If |callback| is nullptr,
1053 * this unsets the callback. |data| will be passed to the callback
1054 * as its last parameter.
1055 */
1056 void SetAtomicsWaitCallback(AtomicsWaitCallback callback, void* data);
1057
1058 /**
1059 * Enables the host application to receive a notification after a
1060 * garbage collection. Allocations are allowed in the callback function,
1061 * but the callback is not re-entrant: if the allocation inside it will
1062 * trigger the garbage collection, the callback won't be called again.
1063 * It is possible to specify the GCType filter for your callback. But it is
1064 * not possible to register the same callback function two times with
1065 * different GCType filters.
1066 */
1067 void AddGCEpilogueCallback(GCCallbackWithData callback, void* data = nullptr,
1068 GCType gc_type_filter = kGCTypeAll);
1069 void AddGCEpilogueCallback(GCCallback callback,
1070 GCType gc_type_filter = kGCTypeAll);
1071
1072 /**
1073 * This function removes callback which was installed by
1074 * AddGCEpilogueCallback function.
1075 */
1076 void RemoveGCEpilogueCallback(GCCallbackWithData callback,
1077 void* data = nullptr);
1078 void RemoveGCEpilogueCallback(GCCallback callback);
1079
1080 using GetExternallyAllocatedMemoryInBytesCallback = size_t (*)();
1081
1082 /**
1083 * Set the callback that tells V8 how much memory is currently allocated
1084 * externally of the V8 heap. Ideally this memory is somehow connected to V8
1085 * objects and may get freed-up when the corresponding V8 objects get
1086 * collected by a V8 garbage collection.
1087 */
1088 void SetGetExternallyAllocatedMemoryInBytesCallback(
1089 GetExternallyAllocatedMemoryInBytesCallback callback);
1090
1091 /**
1092 * Forcefully terminate the current thread of JavaScript execution
1093 * in the given isolate.
1094 *
1095 * This method can be used by any thread even if that thread has not
1096 * acquired the V8 lock with a Locker object.
1097 */
1098 void TerminateExecution();
1099
1100 /**
1101 * Is V8 terminating JavaScript execution.
1102 *
1103 * Returns true if JavaScript execution is currently terminating
1104 * because of a call to TerminateExecution. In that case there are
1105 * still JavaScript frames on the stack and the termination
1106 * exception is still active.
1107 */
1108 bool IsExecutionTerminating();
1109
1110 /**
1111 * Resume execution capability in the given isolate, whose execution
1112 * was previously forcefully terminated using TerminateExecution().
1113 *
1114 * When execution is forcefully terminated using TerminateExecution(),
1115 * the isolate can not resume execution until all JavaScript frames
1116 * have propagated the uncatchable exception which is generated. This
1117 * method allows the program embedding the engine to handle the
1118 * termination event and resume execution capability, even if
1119 * JavaScript frames remain on the stack.
1120 *
1121 * This method can be used by any thread even if that thread has not
1122 * acquired the V8 lock with a Locker object.
1123 */
1124 void CancelTerminateExecution();
1125
1126 /**
1127 * Request V8 to interrupt long running JavaScript code and invoke
1128 * the given |callback| passing the given |data| to it. After |callback|
1129 * returns control will be returned to the JavaScript code.
1130 * There may be a number of interrupt requests in flight.
1131 * Can be called from another thread without acquiring a |Locker|.
1132 * Registered |callback| must not reenter interrupted Isolate.
1133 */
1134 void RequestInterrupt(InterruptCallback callback, void* data);
1135
1136 /**
1137 * Returns true if there is ongoing background work within V8 that will
1138 * eventually post a foreground task, like asynchronous WebAssembly
1139 * compilation.
1140 */
1141 bool HasPendingBackgroundTasks();
1142
1143 /**
1144 * Request garbage collection in this Isolate. It is only valid to call this
1145 * function if --expose_gc was specified.
1146 *
1147 * This should only be used for testing purposes and not to enforce a garbage
1148 * collection schedule. It has strong negative impact on the garbage
1149 * collection performance. Use IdleNotificationDeadline() or
1150 * LowMemoryNotification() instead to influence the garbage collection
1151 * schedule.
1152 */
1153 void RequestGarbageCollectionForTesting(GarbageCollectionType type);
1154
1155 /**
1156 * Request garbage collection with a specific embedderstack state in this
1157 * Isolate. It is only valid to call this function if --expose_gc was
1158 * specified.
1159 *
1160 * This should only be used for testing purposes and not to enforce a garbage
1161 * collection schedule. It has strong negative impact on the garbage
1162 * collection performance. Use IdleNotificationDeadline() or
1163 * LowMemoryNotification() instead to influence the garbage collection
1164 * schedule.
1165 */
1166 void RequestGarbageCollectionForTesting(
1167 GarbageCollectionType type,
1168 EmbedderHeapTracer::EmbedderStackState stack_state);
1169
1170 /**
1171 * Set the callback to invoke for logging event.
1172 */
1173 void SetEventLogger(LogEventCallback that);
1174
1175 /**
1176 * Adds a callback to notify the host application right before a script
1177 * is about to run. If a script re-enters the runtime during executing, the
1178 * BeforeCallEnteredCallback is invoked for each re-entrance.
1179 * Executing scripts inside the callback will re-trigger the callback.
1180 */
1181 void AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback);
1182
1183 /**
1184 * Removes callback that was installed by AddBeforeCallEnteredCallback.
1185 */
1186 void RemoveBeforeCallEnteredCallback(BeforeCallEnteredCallback callback);
1187
1188 /**
1189 * Adds a callback to notify the host application when a script finished
1190 * running. If a script re-enters the runtime during executing, the
1191 * CallCompletedCallback is only invoked when the outer-most script
1192 * execution ends. Executing scripts inside the callback do not trigger
1193 * further callbacks.
1194 */
1195 void AddCallCompletedCallback(CallCompletedCallback callback);
1196
1197 /**
1198 * Removes callback that was installed by AddCallCompletedCallback.
1199 */
1200 void RemoveCallCompletedCallback(CallCompletedCallback callback);
1201
1202 /**
1203 * Set the PromiseHook callback for various promise lifecycle
1204 * events.
1205 */
1206 void SetPromiseHook(PromiseHook hook);
1207
1208 /**
1209 * Set callback to notify about promise reject with no handler, or
1210 * revocation of such a previous notification once the handler is added.
1211 */
1212 void SetPromiseRejectCallback(PromiseRejectCallback callback);
1213
1214 /**
1215 * Runs the default MicrotaskQueue until it gets empty and perform other
1216 * microtask checkpoint steps, such as calling ClearKeptObjects. Asserts that
1217 * the MicrotasksPolicy is not kScoped. Any exceptions thrown by microtask
1218 * callbacks are swallowed.
1219 */
1220 void PerformMicrotaskCheckpoint();
1221
1222 /**
1223 * Enqueues the callback to the default MicrotaskQueue
1224 */
1225 void EnqueueMicrotask(Local<Function> microtask);
1226
1227 /**
1228 * Enqueues the callback to the default MicrotaskQueue
1229 */
1230 void EnqueueMicrotask(MicrotaskCallback callback, void* data = nullptr);
1231
1232 /**
1233 * Controls how Microtasks are invoked. See MicrotasksPolicy for details.
1234 */
1235 void SetMicrotasksPolicy(MicrotasksPolicy policy);
1236
1237 /**
1238 * Returns the policy controlling how Microtasks are invoked.
1239 */
1240 MicrotasksPolicy GetMicrotasksPolicy() const;
1241
1242 /**
1243 * Adds a callback to notify the host application after
1244 * microtasks were run on the default MicrotaskQueue. The callback is
1245 * triggered by explicit RunMicrotasks call or automatic microtasks execution
1246 * (see SetMicrotaskPolicy).
1247 *
1248 * Callback will trigger even if microtasks were attempted to run,
1249 * but the microtasks queue was empty and no single microtask was actually
1250 * executed.
1251 *
1252 * Executing scripts inside the callback will not re-trigger microtasks and
1253 * the callback.
1254 */
1255 void AddMicrotasksCompletedCallback(
1256 MicrotasksCompletedCallbackWithData callback, void* data = nullptr);
1257
1258 /**
1259 * Removes callback that was installed by AddMicrotasksCompletedCallback.
1260 */
1261 void RemoveMicrotasksCompletedCallback(
1262 MicrotasksCompletedCallbackWithData callback, void* data = nullptr);
1263
1264 /**
1265 * Sets a callback for counting the number of times a feature of V8 is used.
1266 */
1267 void SetUseCounterCallback(UseCounterCallback callback);
1268
1269 /**
1270 * Enables the host application to provide a mechanism for recording
1271 * statistics counters.
1272 */
1273 void SetCounterFunction(CounterLookupCallback);
1274
1275 /**
1276 * Enables the host application to provide a mechanism for recording
1277 * histograms. The CreateHistogram function returns a
1278 * histogram which will later be passed to the AddHistogramSample
1279 * function.
1280 */
1281 void SetCreateHistogramFunction(CreateHistogramCallback);
1282 void SetAddHistogramSampleFunction(AddHistogramSampleCallback);
1283
1284 /**
1285 * Enables the host application to provide a mechanism for recording
1286 * event based metrics. In order to use this interface
1287 * include/v8-metrics.h
1288 * needs to be included and the recorder needs to be derived from the
1289 * Recorder base class defined there.
1290 * This method can only be called once per isolate and must happen during
1291 * isolate initialization before background threads are spawned.
1292 */
1293 void SetMetricsRecorder(
1294 const std::shared_ptr<metrics::Recorder>& metrics_recorder);
1295
1296 /**
1297 * Enables the host application to provide a mechanism for recording a
1298 * predefined set of data as crash keys to be used in postmortem debugging in
1299 * case of a crash.
1300 */
1301 void SetAddCrashKeyCallback(AddCrashKeyCallback);
1302
1303 /**
1304 * Optional notification that the embedder is idle.
1305 * V8 uses the notification to perform garbage collection.
1306 * This call can be used repeatedly if the embedder remains idle.
1307 * Returns true if the embedder should stop calling IdleNotificationDeadline
1308 * until real work has been done. This indicates that V8 has done
1309 * as much cleanup as it will be able to do.
1310 *
1311 * The deadline_in_seconds argument specifies the deadline V8 has to finish
1312 * garbage collection work. deadline_in_seconds is compared with
1313 * MonotonicallyIncreasingTime() and should be based on the same timebase as
1314 * that function. There is no guarantee that the actual work will be done
1315 * within the time limit.
1316 */
1317 bool IdleNotificationDeadline(double deadline_in_seconds);
1318
1319 /**
1320 * Optional notification that the system is running low on memory.
1321 * V8 uses these notifications to attempt to free memory.
1322 */
1323 void LowMemoryNotification();
1324
1325 /**
1326 * Optional notification that a context has been disposed. V8 uses these
1327 * notifications to guide the GC heuristic and cancel FinalizationRegistry
1328 * cleanup tasks. Returns the number of context disposals - including this one
1329 * - since the last time V8 had a chance to clean up.
1330 *
1331 * The optional parameter |dependant_context| specifies whether the disposed
1332 * context was depending on state from other contexts or not.
1333 */
1334 int ContextDisposedNotification(bool dependant_context = true);
1335
1336 /**
1337 * Optional notification that the isolate switched to the foreground.
1338 * V8 uses these notifications to guide heuristics.
1339 */
1340 void IsolateInForegroundNotification();
1341
1342 /**
1343 * Optional notification that the isolate switched to the background.
1344 * V8 uses these notifications to guide heuristics.
1345 */
1346 void IsolateInBackgroundNotification();
1347
1348 /**
1349 * Optional notification which will enable the memory savings mode.
1350 * V8 uses this notification to guide heuristics which may result in a
1351 * smaller memory footprint at the cost of reduced runtime performance.
1352 */
1353 void EnableMemorySavingsMode();
1354
1355 /**
1356 * Optional notification which will disable the memory savings mode.
1357 */
1358 void DisableMemorySavingsMode();
1359
1360 /**
1361 * Optional notification to tell V8 the current performance requirements
1362 * of the embedder based on RAIL.
1363 * V8 uses these notifications to guide heuristics.
1364 * This is an unfinished experimental feature. Semantics and implementation
1365 * may change frequently.
1366 */
1367 void SetRAILMode(RAILMode rail_mode);
1368
1369 /**
1370 * Update load start time of the RAIL mode
1371 */
1372 void UpdateLoadStartTime();
1373
1374 /**
1375 * Optional notification to tell V8 the current isolate is used for debugging
1376 * and requires higher heap limit.
1377 */
1378 void IncreaseHeapLimitForDebugging();
1379
1380 /**
1381 * Restores the original heap limit after IncreaseHeapLimitForDebugging().
1382 */
1383 void RestoreOriginalHeapLimit();
1384
1385 /**
1386 * Returns true if the heap limit was increased for debugging and the
1387 * original heap limit was not restored yet.
1388 */
1389 bool IsHeapLimitIncreasedForDebugging();
1390
1391 /**
1392 * Allows the host application to provide the address of a function that is
1393 * notified each time code is added, moved or removed.
1394 *
1395 * \param options options for the JIT code event handler.
1396 * \param event_handler the JIT code event handler, which will be invoked
1397 * each time code is added, moved or removed.
1398 * \note \p event_handler won't get notified of existent code.
1399 * \note since code removal notifications are not currently issued, the
1400 * \p event_handler may get notifications of code that overlaps earlier
1401 * code notifications. This happens when code areas are reused, and the
1402 * earlier overlapping code areas should therefore be discarded.
1403 * \note the events passed to \p event_handler and the strings they point to
1404 * are not guaranteed to live past each call. The \p event_handler must
1405 * copy strings and other parameters it needs to keep around.
1406 * \note the set of events declared in JitCodeEvent::EventType is expected to
1407 * grow over time, and the JitCodeEvent structure is expected to accrue
1408 * new members. The \p event_handler function must ignore event codes
1409 * it does not recognize to maintain future compatibility.
1410 * \note Use Isolate::CreateParams to get events for code executed during
1411 * Isolate setup.
1412 */
1413 void SetJitCodeEventHandler(JitCodeEventOptions options,
1414 JitCodeEventHandler event_handler);
1415
1416 /**
1417 * Modifies the stack limit for this Isolate.
1418 *
1419 * \param stack_limit An address beyond which the Vm's stack may not grow.
1420 *
1421 * \note If you are using threads then you should hold the V8::Locker lock
1422 * while setting the stack limit and you must set a non-default stack
1423 * limit separately for each thread.
1424 */
1425 void SetStackLimit(uintptr_t stack_limit);
1426
1427 /**
1428 * Returns a memory range that can potentially contain jitted code. Code for
1429 * V8's 'builtins' will not be in this range if embedded builtins is enabled.
1430 *
1431 * On Win64, embedders are advised to install function table callbacks for
1432 * these ranges, as default SEH won't be able to unwind through jitted code.
1433 * The first page of the code range is reserved for the embedder and is
1434 * committed, writable, and executable, to be used to store unwind data, as
1435 * documented in
1436 * https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64.
1437 *
1438 * Might be empty on other platforms.
1439 *
1440 * https://code.google.com/p/v8/issues/detail?id=3598
1441 */
1442 void GetCodeRange(void** start, size_t* length_in_bytes);
1443
1444 /**
1445 * As GetCodeRange, but for embedded builtins (these live in a distinct
1446 * memory region from other V8 Code objects).
1447 */
1448 void GetEmbeddedCodeRange(const void** start, size_t* length_in_bytes);
1449
1450 /**
1451 * Returns the JSEntryStubs necessary for use with the Unwinder API.
1452 */
1453 JSEntryStubs GetJSEntryStubs();
1454
1455 static constexpr size_t kMinCodePagesBufferSize = 32;
1456
1457 /**
1458 * Copies the code heap pages currently in use by V8 into |code_pages_out|.
1459 * |code_pages_out| must have at least kMinCodePagesBufferSize capacity and
1460 * must be empty.
1461 *
1462 * Signal-safe, does not allocate, does not access the V8 heap.
1463 * No code on the stack can rely on pages that might be missing.
1464 *
1465 * Returns the number of pages available to be copied, which might be greater
1466 * than |capacity|. In this case, only |capacity| pages will be copied into
1467 * |code_pages_out|. The caller should provide a bigger buffer on the next
1468 * call in order to get all available code pages, but this is not required.
1469 */
1470 size_t CopyCodePages(size_t capacity, MemoryRange* code_pages_out);
1471
1472 /** Set the callback to invoke in case of fatal errors. */
1473 void SetFatalErrorHandler(FatalErrorCallback that);
1474
1475 /** Set the callback to invoke in case of OOM errors. */
1476 void SetOOMErrorHandler(OOMErrorCallback that);
1477
1478 /**
1479 * Add a callback to invoke in case the heap size is close to the heap limit.
1480 * If multiple callbacks are added, only the most recently added callback is
1481 * invoked.
1482 */
1483 void AddNearHeapLimitCallback(NearHeapLimitCallback callback, void* data);
1484
1485 /**
1486 * Remove the given callback and restore the heap limit to the
1487 * given limit. If the given limit is zero, then it is ignored.
1488 * If the current heap size is greater than the given limit,
1489 * then the heap limit is restored to the minimal limit that
1490 * is possible for the current heap size.
1491 */
1492 void RemoveNearHeapLimitCallback(NearHeapLimitCallback callback,
1493 size_t heap_limit);
1494
1495 /**
1496 * If the heap limit was changed by the NearHeapLimitCallback, then the
1497 * initial heap limit will be restored once the heap size falls below the
1498 * given threshold percentage of the initial heap limit.
1499 * The threshold percentage is a number in (0.0, 1.0) range.
1500 */
1501 void AutomaticallyRestoreInitialHeapLimit(double threshold_percent = 0.5);
1502
1503 /**
1504 * Set the callback to invoke to check if code generation from
1505 * strings should be allowed.
1506 */
1507 void SetModifyCodeGenerationFromStringsCallback(
1508 ModifyCodeGenerationFromStringsCallback2 callback);
1509
1510 /**
1511 * Set the callback to invoke to check if wasm code generation should
1512 * be allowed.
1513 */
1514 void SetAllowWasmCodeGenerationCallback(
1515 AllowWasmCodeGenerationCallback callback);
1516
1517 /**
1518 * Embedder over{ride|load} injection points for wasm APIs. The expectation
1519 * is that the embedder sets them at most once.
1520 */
1521 void SetWasmModuleCallback(ExtensionCallback callback);
1522 void SetWasmInstanceCallback(ExtensionCallback callback);
1523
1524 void SetWasmStreamingCallback(WasmStreamingCallback callback);
1525
1526 void SetWasmLoadSourceMapCallback(WasmLoadSourceMapCallback callback);
1527
1528 void SetWasmSimdEnabledCallback(WasmSimdEnabledCallback callback);
1529
1530 void SetWasmExceptionsEnabledCallback(WasmExceptionsEnabledCallback callback);
1531
1532 void SetWasmDynamicTieringEnabledCallback(
1533 WasmDynamicTieringEnabledCallback callback);
1534
1535 void SetSharedArrayBufferConstructorEnabledCallback(
1536 SharedArrayBufferConstructorEnabledCallback callback);
1537
1538 /**
1539 * This function can be called by the embedder to signal V8 that the dynamic
1540 * enabling of features has finished. V8 can now set up dynamically added
1541 * features.
1542 */
1543 void InstallConditionalFeatures(Local<Context> context);
1544
1545 /**
1546 * Check if V8 is dead and therefore unusable. This is the case after
1547 * fatal errors such as out-of-memory situations.
1548 */
1549 bool IsDead();
1550
1551 /**
1552 * Adds a message listener (errors only).
1553 *
1554 * The same message listener can be added more than once and in that
1555 * case it will be called more than once for each message.
1556 *
1557 * If data is specified, it will be passed to the callback when it is called.
1558 * Otherwise, the exception object will be passed to the callback instead.
1559 */
1560 bool AddMessageListener(MessageCallback that,
1561 Local<Value> data = Local<Value>());
1562
1563 /**
1564 * Adds a message listener.
1565 *
1566 * The same message listener can be added more than once and in that
1567 * case it will be called more than once for each message.
1568 *
1569 * If data is specified, it will be passed to the callback when it is called.
1570 * Otherwise, the exception object will be passed to the callback instead.
1571 *
1572 * A listener can listen for particular error levels by providing a mask.
1573 */
1574 bool AddMessageListenerWithErrorLevel(MessageCallback that,
1575 int message_levels,
1576 Local<Value> data = Local<Value>());
1577
1578 /**
1579 * Remove all message listeners from the specified callback function.
1580 */
1581 void RemoveMessageListeners(MessageCallback that);
1582
1583 /** Callback function for reporting failed access checks.*/
1584 void SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback);
1585
1586 /**
1587 * Tells V8 to capture current stack trace when uncaught exception occurs
1588 * and report it to the message listeners. The option is off by default.
1589 */
1590 void SetCaptureStackTraceForUncaughtExceptions(
1591 bool capture, int frame_limit = 10,
1592 StackTrace::StackTraceOptions options = StackTrace::kOverview);
1593
1594 /**
1595 * Iterates through all external resources referenced from current isolate
1596 * heap. GC is not invoked prior to iterating, therefore there is no
1597 * guarantee that visited objects are still alive.
1598 */
1599 void VisitExternalResources(ExternalResourceVisitor* visitor);
1600
1601 /**
1602 * Iterates through all the persistent handles in the current isolate's heap
1603 * that have class_ids.
1604 */
1605 void VisitHandlesWithClassIds(PersistentHandleVisitor* visitor);
1606
1607 /**
1608 * Iterates through all the persistent handles in the current isolate's heap
1609 * that have class_ids and are weak to be marked as inactive if there is no
1610 * pending activity for the handle.
1611 */
1612 void VisitWeakHandles(PersistentHandleVisitor* visitor);
1613
1614 /**
1615 * Check if this isolate is in use.
1616 * True if at least one thread Enter'ed this isolate.
1617 */
1618 bool IsInUse();
1619
1620 /**
1621 * Set whether calling Atomics.wait (a function that may block) is allowed in
1622 * this isolate. This can also be configured via
1623 * CreateParams::allow_atomics_wait.
1624 */
1625 void SetAllowAtomicsWait(bool allow);
1626
1627 /**
1628 * Time zone redetection indicator for
1629 * DateTimeConfigurationChangeNotification.
1630 *
1631 * kSkip indicates V8 that the notification should not trigger redetecting
1632 * host time zone. kRedetect indicates V8 that host time zone should be
1633 * redetected, and used to set the default time zone.
1634 *
1635 * The host time zone detection may require file system access or similar
1636 * operations unlikely to be available inside a sandbox. If v8 is run inside a
1637 * sandbox, the host time zone has to be detected outside the sandbox before
1638 * calling DateTimeConfigurationChangeNotification function.
1639 */
1640 enum class TimeZoneDetection { kSkip, kRedetect };
1641
1642 /**
1643 * Notification that the embedder has changed the time zone, daylight savings
1644 * time or other date / time configuration parameters. V8 keeps a cache of
1645 * various values used for date / time computation. This notification will
1646 * reset those cached values for the current context so that date / time
1647 * configuration changes would be reflected.
1648 *
1649 * This API should not be called more than needed as it will negatively impact
1650 * the performance of date operations.
1651 */
1652 void DateTimeConfigurationChangeNotification(
1653 TimeZoneDetection time_zone_detection = TimeZoneDetection::kSkip);
1654
1655 /**
1656 * Notification that the embedder has changed the locale. V8 keeps a cache of
1657 * various values used for locale computation. This notification will reset
1658 * those cached values for the current context so that locale configuration
1659 * changes would be reflected.
1660 *
1661 * This API should not be called more than needed as it will negatively impact
1662 * the performance of locale operations.
1663 */
1664 void LocaleConfigurationChangeNotification();
1665
1666 Isolate() = delete;
1667 ~Isolate() = delete;
1668 Isolate(const Isolate&) = delete;
1669 Isolate& operator=(const Isolate&) = delete;
1670 // Deleting operator new and delete here is allowed as ctor and dtor is also
1671 // deleted.
1672 void* operator new(size_t size) = delete;
1673 void* operator new[](size_t size) = delete;
1674 void operator delete(void*, size_t) = delete;
1675 void operator delete[](void*, size_t) = delete;
1676
1677 private:
1678 template <class K, class V, class Traits>
1679 friend class PersistentValueMapBase;
1680
1681 internal::Address* GetDataFromSnapshotOnce(size_t index);
1682 void ReportExternalAllocationLimitReached();
1683 };
1684
SetData(uint32_t slot,void * data)1685 void Isolate::SetData(uint32_t slot, void* data) {
1686 using I = internal::Internals;
1687 I::SetEmbedderData(this, slot, data);
1688 }
1689
GetData(uint32_t slot)1690 void* Isolate::GetData(uint32_t slot) {
1691 using I = internal::Internals;
1692 return I::GetEmbedderData(this, slot);
1693 }
1694
GetNumberOfDataSlots()1695 uint32_t Isolate::GetNumberOfDataSlots() {
1696 using I = internal::Internals;
1697 return I::kNumIsolateDataSlots;
1698 }
1699
1700 template <class T>
GetDataFromSnapshotOnce(size_t index)1701 MaybeLocal<T> Isolate::GetDataFromSnapshotOnce(size_t index) {
1702 T* data = reinterpret_cast<T*>(GetDataFromSnapshotOnce(index));
1703 if (data) internal::PerformCastCheck(data);
1704 return Local<T>(data);
1705 }
1706
1707 } // namespace v8
1708
1709 #endif // INCLUDE_V8_ISOLATE_H_
1710