diff options
Diffstat (limited to 'deps/v8/include/v8.h')
-rw-r--r-- | deps/v8/include/v8.h | 335 |
1 files changed, 291 insertions, 44 deletions
diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index e1a467ddee..d66f360c99 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -19,6 +19,7 @@ #include <stdint.h> #include <stdio.h> #include <memory> +#include <type_traits> #include <utility> #include <vector> @@ -128,6 +129,7 @@ class PropertyCallbackArguments; class FunctionCallbackArguments; class GlobalHandles; class ScopedExternalStringLock; +class ThreadLocalTop; namespace wasm { class NativeModule; @@ -790,24 +792,43 @@ template <class T> using UniquePersistent = Global<T>; /** - * A traced handle with move semantics, similar to std::unique_ptr. The handle - * is to be used together with |v8::EmbedderHeapTracer| and specifies edges from - * the embedder into V8's heap. + * Trait specifying behavior of |TracedGlobal<T>|. + */ +template <typename T> +struct TracedGlobalTrait { + /** + * Specifies whether |TracedGlobal<T>| should clear its handle on destruction. + * + * V8 will *not* clear the embedder-side memory of the handle. The embedder is + * expected to report all |TracedGlobal<T>| handles through + * |EmbedderHeapTracer| upon garabge collection. + * + * See |EmbedderHeapTracer::IsRootForNonTracingGC| for handling with + * non-tracing GCs in V8. + */ + static constexpr bool kRequiresExplicitDestruction = true; +}; + +/** + * A traced handle with copy and move semantics. The handle is to be used + * together with |v8::EmbedderHeapTracer| and specifies edges from the embedder + * into V8's heap. * * The exact semantics are: * - Tracing garbage collections use |v8::EmbedderHeapTracer|. * - Non-tracing garbage collections refer to * |v8::EmbedderHeapTracer::IsRootForNonTracingGC()| whether the handle should * be treated as root or not. + * + * For destruction semantics see |TracedGlobalTrait<T>|. */ template <typename T> -class V8_EXPORT TracedGlobal { +class TracedGlobal { public: /** * An empty TracedGlobal without storage cell. */ TracedGlobal() = default; - ~TracedGlobal() { Reset(); } /** * Construct a TracedGlobal from a Local. @@ -824,7 +845,41 @@ class V8_EXPORT TracedGlobal { /** * Move constructor initializing TracedGlobal from an existing one. */ - V8_INLINE TracedGlobal(TracedGlobal&& other); + V8_INLINE TracedGlobal(TracedGlobal&& other) { + // Forward to operator=. + *this = std::move(other); + } + + /** + * Move constructor initializing TracedGlobal from an existing one. + */ + template <typename S> + V8_INLINE TracedGlobal(TracedGlobal<S>&& other) { + // Forward to operator=. + *this = std::move(other); + } + + /** + * Copy constructor initializing TracedGlobal from an existing one. + */ + V8_INLINE TracedGlobal(const TracedGlobal& other) { + // Forward to operator=; + *this = other; + } + + /** + * Copy constructor initializing TracedGlobal from an existing one. + */ + template <typename S> + V8_INLINE TracedGlobal(const TracedGlobal<S>& other) { + // Forward to operator=; + *this = other; + } + + /** + * Move assignment operator initializing TracedGlobal from an existing one. + */ + V8_INLINE TracedGlobal& operator=(TracedGlobal&& rhs); /** * Move assignment operator initializing TracedGlobal from an existing one. @@ -833,10 +888,21 @@ class V8_EXPORT TracedGlobal { V8_INLINE TracedGlobal& operator=(TracedGlobal<S>&& rhs); /** - * TracedGlobal only supports move semantics and forbids copying. + * Copy assignment operator initializing TracedGlobal from an existing one. + * + * Note: Prohibited when |other| has a finalization callback set through + * |SetFinalizationCallback|. + */ + V8_INLINE TracedGlobal& operator=(const TracedGlobal& rhs); + + /** + * Copy assignment operator initializing TracedGlobal from an existing one. + * + * Note: Prohibited when |other| has a finalization callback set through + * |SetFinalizationCallback|. */ - TracedGlobal(const TracedGlobal&) = delete; - void operator=(const TracedGlobal&) = delete; + template <class S> + V8_INLINE TracedGlobal& operator=(const TracedGlobal<S>& rhs); /** * Returns true if this TracedGlobal is empty, i.e., has not been assigned an @@ -870,8 +936,8 @@ class V8_EXPORT TracedGlobal { template <class S> V8_INLINE bool operator==(const TracedGlobal<S>& that) const { - internal::Address* a = reinterpret_cast<internal::Address*>(this->val_); - internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); + internal::Address* a = reinterpret_cast<internal::Address*>(**this); + internal::Address* b = reinterpret_cast<internal::Address*>(*that); if (a == nullptr) return b == nullptr; if (b == nullptr) return false; return *a == *b; @@ -879,8 +945,8 @@ class V8_EXPORT TracedGlobal { template <class S> V8_INLINE bool operator==(const Local<S>& that) const { - internal::Address* a = reinterpret_cast<internal::Address*>(this->val_); - internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); + internal::Address* a = reinterpret_cast<internal::Address*>(**this); + internal::Address* b = reinterpret_cast<internal::Address*>(*that); if (a == nullptr) return b == nullptr; if (b == nullptr) return false; return *a == *b; @@ -921,11 +987,32 @@ class V8_EXPORT TracedGlobal { void* parameter, WeakCallbackInfo<void>::Callback callback); private: - V8_INLINE static T* New(Isolate* isolate, T* that, T** slot); + // Wrapping type used when clearing on destruction is required. + struct WrappedForDestruction { + T* value; + + explicit WrappedForDestruction(T* val) : value(val) {} + ~WrappedForDestruction(); + operator T*() const { return value; } + T* operator*() const { return value; } + T* operator->() const { return value; } + WrappedForDestruction& operator=(const WrappedForDestruction& other) { + value = other.value; + return *this; + } + WrappedForDestruction& operator=(T* val) { + value = val; + return *this; + } + }; + + V8_INLINE static T* New(Isolate* isolate, T* that, void* slot); T* operator*() const { return this->val_; } - T* val_ = nullptr; + typename std::conditional< + TracedGlobalTrait<TracedGlobal<T>>::kRequiresExplicitDestruction, + WrappedForDestruction, T*>::type val_{nullptr}; friend class EmbedderHeapTracer; template <typename F> @@ -1968,6 +2055,7 @@ struct SampleInfo { StateTag vm_state; // Current VM state. void* external_callback_entry; // External callback address if VM is // executing an external callback. + void* top_context; // Incumbent native context address. }; struct MemoryRange { @@ -3698,6 +3786,15 @@ class V8_EXPORT Object : public Value { bool IsConstructor(); /** + * True if this object can carry information relevant to the embedder in its + * embedder fields, false otherwise. This is generally true for objects + * constructed through function templates but also holds for other types where + * V8 automatically adds internal fields at compile time, such as e.g. + * v8::ArrayBuffer. + */ + bool IsApiWrapper(); + + /** * Call an Object as a function if a callback is set by the * ObjectTemplate::SetCallAsFunctionHandler method. */ @@ -4762,8 +4859,8 @@ class V8_EXPORT ArrayBuffer : public Object { bool IsDetachable() const; // TODO(913887): fix the use of 'neuter' in the API. - V8_DEPRECATE_SOON("Use IsDetachable() instead.", - inline bool IsNeuterable() const) { + V8_DEPRECATED("Use IsDetachable() instead.", + inline bool IsNeuterable() const) { return IsDetachable(); } @@ -4776,7 +4873,7 @@ class V8_EXPORT ArrayBuffer : public Object { void Detach(); // TODO(913887): fix the use of 'neuter' in the API. - V8_DEPRECATE_SOON("Use Detach() instead.", inline void Neuter()) { Detach(); } + V8_DEPRECATED("Use Detach() instead.", inline void Neuter()) { Detach(); } /** * Make this ArrayBuffer external. The pointer to underlying memory block @@ -5379,6 +5476,32 @@ class V8_EXPORT RegExp : public Object { static void CheckCast(Value* obj); }; +/** + * An instance of the built-in FinalizationGroup constructor. + * + * This API is experimental and may change significantly. + */ +class V8_EXPORT FinalizationGroup : public Object { + public: + /** + * Runs the cleanup callback of the given FinalizationGroup. + * + * V8 will inform the embedder that there are finalizer callbacks be + * called through HostCleanupFinalizationGroupCallback. + * + * HostCleanupFinalizationGroupCallback should schedule a task to + * call FinalizationGroup::Cleanup() at some point in the + * future. It's the embedders responsiblity to make this call at a + * time which does not interrupt synchronous ECMAScript code + * execution. + * + * If the result is Nothing<bool> then an exception has + * occurred. Otherwise the result is |true| if the cleanup callback + * was called successfully. The result is never |false|. + */ + static V8_WARN_UNUSED_RESULT Maybe<bool> Cleanup( + Local<FinalizationGroup> finalization_group); +}; /** * A JavaScript value that wraps a C++ void*. This type of value is mainly used @@ -6439,11 +6562,18 @@ class V8_EXPORT ResourceConstraints { * provided heap size limit. The heap size includes both the young and * the old generation. * + * \param initial_heap_size_in_bytes The initial heap size or zero. + * By default V8 starts with a small heap and dynamically grows it to + * match the set of live objects. This may lead to ineffective + * garbage collections at startup if the live set is large. + * Setting the initial heap size avoids such garbage collections. + * Note that this does not affect young generation garbage collections. + * * \param maximum_heap_size_in_bytes The hard limit for the heap size. * When the heap size approaches this limit, V8 will perform series of - * garbage collections and invoke the NearHeapLimitCallback. - * If the garbage collections do not help and the callback does not - * increase the limit, then V8 will crash with V8::FatalProcessOutOfMemory. + * garbage collections and invoke the NearHeapLimitCallback. If the garbage + * collections do not help and the callback does not increase the limit, + * then V8 will crash with V8::FatalProcessOutOfMemory. */ void ConfigureDefaultsFromHeapSize(size_t initial_heap_size_in_bytes, size_t maximum_heap_size_in_bytes); @@ -6611,11 +6741,35 @@ typedef void* (*CreateHistogramCallback)(const char* name, typedef void (*AddHistogramSampleCallback)(void* histogram, int sample); +// --- Crashkeys Callback --- +enum class CrashKeyId { + kIsolateAddress, + kReadonlySpaceFirstPageAddress, + kMapSpaceFirstPageAddress, + kCodeSpaceFirstPageAddress, +}; + +typedef void (*AddCrashKeyCallback)(CrashKeyId id, const std::string& value); + // --- Enter/Leave Script Callback --- typedef void (*BeforeCallEnteredCallback)(Isolate*); typedef void (*CallCompletedCallback)(Isolate*); /** + * HostCleanupFinalizationGroupCallback is called when we require the + * embedder to enqueue a task that would call + * FinalizationGroup::Cleanup(). + * + * The FinalizationGroup is the one for which the embedder needs to + * call FinalizationGroup::Cleanup() on. + * + * The context provided is the one in which the FinalizationGroup was + * created in. + */ +typedef void (*HostCleanupFinalizationGroupCallback)( + Local<Context> context, Local<FinalizationGroup> fg); + +/** * HostImportModuleDynamicallyCallback is called when we require the * embedder to load a module. This is used as part of the dynamic * import syntax. @@ -6712,7 +6866,8 @@ class PromiseRejectMessage { typedef void (*PromiseRejectCallback)(PromiseRejectMessage message); // --- Microtasks Callbacks --- -typedef void (*MicrotasksCompletedCallback)(Isolate*); +V8_DEPRECATE_SOON("Use *WithData version.", + typedef void (*MicrotasksCompletedCallback)(Isolate*)); typedef void (*MicrotasksCompletedCallbackWithData)(Isolate*, void*); typedef void (*MicrotaskCallback)(void* data); @@ -6884,6 +7039,10 @@ typedef void (*WasmStreamingCallback)(const FunctionCallbackInfo<Value>&); // --- Callback for checking if WebAssembly threads are enabled --- typedef bool (*WasmThreadsEnabledCallback)(Local<Context> context); +// --- Callback for loading source map file for WASM profiling support +typedef Local<String> (*WasmLoadSourceMapCallback)(Isolate* isolate, + const char* name); + // --- Garbage Collection Callbacks --- /** @@ -7260,7 +7419,7 @@ class V8_EXPORT EmbedderHeapTracer { /** * Called at the beginning of a GC cycle. */ - V8_DEPRECATE_SOON("Use version with flags.", virtual void TracePrologue()) {} + V8_DEPRECATED("Use version with flags.", virtual void TracePrologue()) {} virtual void TracePrologue(TraceFlags flags); /** @@ -7288,8 +7447,9 @@ class V8_EXPORT EmbedderHeapTracer { * overriden to fill a |TraceSummary| that is used by V8 to schedule future * garbage collections. */ - virtual void TraceEpilogue() {} - virtual void TraceEpilogue(TraceSummary* trace_summary) { TraceEpilogue(); } + V8_DEPRECATE_SOON("Use version with parameter.", + virtual void TraceEpilogue()) {} + virtual void TraceEpilogue(TraceSummary* trace_summary); /** * Called upon entering the final marking pause. No more incremental marking @@ -7311,14 +7471,37 @@ class V8_EXPORT EmbedderHeapTracer { /** * Returns true if the TracedGlobal handle should be considered as root for * the currently running non-tracing garbage collection and false otherwise. + * The default implementation will keep all TracedGlobal references as roots. + * + * If this returns false, then V8 may decide that the object referred to by + * such a handle is reclaimed. In that case: + * - No action is required if handles are used with destructors. + * - When run without destructors (by specializing + * |TracedGlobalTrait::kRequiresExplicitDestruction|) V8 calls + * |ResetHandleInNonTracingGC|. * - * Default implementation will keep all TracedGlobal references as roots. + * Note that the |handle| is different from the |TracedGlobal<T>| handle that + * the embedder holds for retaining the object. The embedder may use + * |TracedGlobal<T>::WrapperClassId()| to distinguish cases where it wants + * handles to be treated as roots from not being treated as roots. */ virtual bool IsRootForNonTracingGC( const v8::TracedGlobal<v8::Value>& handle) { return true; } + /** + * Used in combination with |IsRootForNonTracingGC|. Called by V8 when an + * object that is backed by a handle is reclaimed by a non-tracing garbage + * collection. It is up to the embedder to reset the original handle. + * + * Note that the |handle| is different from the |TracedGlobal<T>| handle that + * the embedder holds for retaining the object. It is up to the embedder to + * find the orignal |TracedGlobal<T>| handle via the object or class id. + */ + virtual void ResetHandleInNonTracingGC( + const v8::TracedGlobal<v8::Value>& handle) {} + /* * Called by the embedder to immediately perform a full garbage collection. * @@ -7550,6 +7733,9 @@ class V8_EXPORT Isolate { private: internal::Isolate* const isolate_; internal::MicrotaskQueue* const microtask_queue_; + internal::Address previous_stack_height_; + + friend class internal::ThreadLocalTop; }; /** @@ -7663,9 +7849,10 @@ class V8_EXPORT Isolate { kStringNormalize = 75, kCallSiteAPIGetFunctionSloppyCall = 76, kCallSiteAPIGetThisSloppyCall = 77, + kRegExpMatchAllWithNonGlobalRegExp = 78, // If you add new values here, you'll also need to update Chromium's: - // web_feature.mojom, UseCounterCallback.cpp, and enums.xml. V8 changes to + // web_feature.mojom, use_counter_callback.cc, and enums.xml. V8 changes to // this list need to be landed first, then changes on the Chromium side. kUseCounterFeatureCount // This enum value must be last. }; @@ -7724,6 +7911,18 @@ class V8_EXPORT Isolate { static Isolate* GetCurrent(); /** + * Clears the set of objects held strongly by the heap. This set of + * objects are originally built when a WeakRef is created or + * successfully dereferenced. + * + * The embedder is expected to call this when a synchronous sequence + * of ECMAScript execution completes. It's the embedders + * responsiblity to make this call at a time which does not + * interrupt synchronous ECMAScript code execution. + */ + void ClearKeptObjects(); + + /** * Custom callback used by embedders to help V8 determine if it should abort * when it throws and no internal handler is predicted to catch the * exception. If --abort-on-uncaught-exception is used on the command line, @@ -7737,6 +7936,14 @@ class V8_EXPORT Isolate { AbortOnUncaughtExceptionCallback callback); /** + * This specifies the callback to be called when finalization groups + * are ready to be cleaned up and require FinalizationGroup::Cleanup() + * to be called in a future task. + */ + void SetHostCleanupFinalizationGroupCallback( + HostCleanupFinalizationGroupCallback callback); + + /** * This specifies the callback called by the upcoming dynamic * import() language feature to load modules. */ @@ -8290,6 +8497,13 @@ class V8_EXPORT Isolate { void SetAddHistogramSampleFunction(AddHistogramSampleCallback); /** + * Enables the host application to provide a mechanism for recording a + * predefined set of data as crash keys to be used in postmortem debugging in + * case of a crash. + */ + void SetAddCrashKeyCallback(AddCrashKeyCallback); + + /** * Optional notification that the embedder is idle. * V8 uses the notification to perform garbage collection. * This call can be used repeatedly if the embedder remains idle. @@ -8488,6 +8702,8 @@ class V8_EXPORT Isolate { void SetWasmThreadsEnabledCallback(WasmThreadsEnabledCallback callback); + void SetWasmLoadSourceMapCallback(WasmLoadSourceMapCallback callback); + /** * Check if V8 is dead and therefore unusable. This is the case after * fatal errors such as out-of-memory situations. @@ -8850,11 +9066,14 @@ class V8_EXPORT V8 { internal::Address* handle); static internal::Address* GlobalizeTracedReference(internal::Isolate* isolate, internal::Address* handle, - internal::Address* slot); + internal::Address* slot, + bool has_destructor); static void MoveGlobalReference(internal::Address** from, internal::Address** to); static void MoveTracedGlobalReference(internal::Address** from, internal::Address** to); + static void CopyTracedGlobalReference(const internal::Address* const* from, + internal::Address** to); static internal::Address* CopyGlobalReference(internal::Address* from); static void DisposeGlobal(internal::Address* global_handle); static void DisposeTracedGlobal(internal::Address* global_handle); @@ -9937,18 +10156,26 @@ Global<T>& Global<T>::operator=(Global<S>&& rhs) { } template <class T> -T* TracedGlobal<T>::New(Isolate* isolate, T* that, T** slot) { +TracedGlobal<T>::WrappedForDestruction::~WrappedForDestruction() { + if (value == nullptr) return; + V8::DisposeTracedGlobal(reinterpret_cast<internal::Address*>(value)); + value = nullptr; +} + +template <class T> +T* TracedGlobal<T>::New(Isolate* isolate, T* that, void* slot) { if (that == nullptr) return nullptr; internal::Address* p = reinterpret_cast<internal::Address*>(that); return reinterpret_cast<T*>(V8::GlobalizeTracedReference( reinterpret_cast<internal::Isolate*>(isolate), p, - reinterpret_cast<internal::Address*>(slot))); + reinterpret_cast<internal::Address*>(slot), + TracedGlobalTrait<TracedGlobal<T>>::kRequiresExplicitDestruction)); } template <class T> void TracedGlobal<T>::Reset() { if (IsEmpty()) return; - V8::DisposeTracedGlobal(reinterpret_cast<internal::Address*>(val_)); + V8::DisposeTracedGlobal(reinterpret_cast<internal::Address*>(**this)); val_ = nullptr; } @@ -9962,19 +10189,23 @@ void TracedGlobal<T>::Reset(Isolate* isolate, const Local<S>& other) { } template <class T> -TracedGlobal<T>::TracedGlobal(TracedGlobal&& other) : val_(other.val_) { - if (other.val_ != nullptr) { - V8::MoveTracedGlobalReference( - reinterpret_cast<internal::Address**>(&other.val_), - reinterpret_cast<internal::Address**>(&this->val_)); - other.val_ = nullptr; - } +template <class S> +TracedGlobal<T>& TracedGlobal<T>::operator=(TracedGlobal<S>&& rhs) { + TYPE_CHECK(T, S); + *this = std::move(rhs.template As<T>()); + return *this; } template <class T> template <class S> -TracedGlobal<T>& TracedGlobal<T>::operator=(TracedGlobal<S>&& rhs) { +TracedGlobal<T>& TracedGlobal<T>::operator=(const TracedGlobal<S>& rhs) { TYPE_CHECK(T, S); + *this = rhs.template As<T>(); + return *this; +} + +template <class T> +TracedGlobal<T>& TracedGlobal<T>::operator=(TracedGlobal&& rhs) { if (this != &rhs) { this->Reset(); if (rhs.val_ != nullptr) { @@ -9989,10 +10220,23 @@ TracedGlobal<T>& TracedGlobal<T>::operator=(TracedGlobal<S>&& rhs) { } template <class T> +TracedGlobal<T>& TracedGlobal<T>::operator=(const TracedGlobal& rhs) { + if (this != &rhs) { + this->Reset(); + if (rhs.val_ != nullptr) { + V8::CopyTracedGlobalReference( + reinterpret_cast<const internal::Address* const*>(&rhs.val_), + reinterpret_cast<internal::Address**>(&this->val_)); + } + } + return *this; +} + +template <class T> void TracedGlobal<T>::SetWrapperClassId(uint16_t class_id) { typedef internal::Internals I; if (IsEmpty()) return; - internal::Address* obj = reinterpret_cast<internal::Address*>(this->val_); + internal::Address* obj = reinterpret_cast<internal::Address*>(**this); uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; *reinterpret_cast<uint16_t*>(addr) = class_id; } @@ -10001,7 +10245,7 @@ template <class T> uint16_t TracedGlobal<T>::WrapperClassId() const { typedef internal::Internals I; if (IsEmpty()) return 0; - internal::Address* obj = reinterpret_cast<internal::Address*>(this->val_); + internal::Address* obj = reinterpret_cast<internal::Address*>(**this); uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; return *reinterpret_cast<uint16_t*>(addr); } @@ -10010,7 +10254,7 @@ template <class T> void TracedGlobal<T>::SetFinalizationCallback( void* parameter, typename WeakCallbackInfo<void>::Callback callback) { V8::SetFinalizationCallbackTraced( - reinterpret_cast<internal::Address*>(this->val_), parameter, callback); + reinterpret_cast<internal::Address*>(**this), parameter, callback); } template <typename T> @@ -10944,9 +11188,12 @@ int64_t Isolate::AdjustAmountOfExternalAllocatedMemory( } if (change_in_bytes < 0) { - const int64_t lower_limit = *external_memory_limit + change_in_bytes; - if (lower_limit > I::kExternalAllocationSoftLimit) + const int64_t lower_limit = + static_cast<int64_t>(static_cast<uint64_t>(*external_memory_limit) + + static_cast<uint64_t>(change_in_bytes)); + if (lower_limit > I::kExternalAllocationSoftLimit) { *external_memory_limit = lower_limit; + } } else if (change_in_bytes > 0 && amount > *external_memory_limit) { ReportExternalAllocationLimitReached(); } |