diff options
Diffstat (limited to 'deps/v8/include/v8.h')
-rw-r--r-- | deps/v8/include/v8.h | 743 |
1 files changed, 497 insertions, 246 deletions
diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 9d0b6a6c65..1387f74715 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -97,6 +97,10 @@ template <class T> class Global; template <class T> class TracedGlobal; +template <class T> +class TracedReference; +template <class T> +class TracedReferenceBase; template<class K, class V, class T> class PersistentValueMap; template <class K, class V, class T> class PersistentValueMapBase; @@ -282,7 +286,8 @@ class Local { V8_INLINE static Local<T> New(Isolate* isolate, Local<T> that); V8_INLINE static Local<T> New(Isolate* isolate, const PersistentBase<T>& that); - V8_INLINE static Local<T> New(Isolate* isolate, const TracedGlobal<T>& that); + V8_INLINE static Local<T> New(Isolate* isolate, + const TracedReferenceBase<T>& that); private: friend class Utils; @@ -312,7 +317,13 @@ class Local { template <class F> friend class ReturnValue; template <class F> + friend class Traced; + template <class F> friend class TracedGlobal; + template <class F> + friend class TracedReferenceBase; + template <class F> + friend class TracedReference; explicit V8_INLINE Local(T* that) : val_(that) {} V8_INLINE static Local<T> New(Isolate* isolate, T* that); @@ -793,22 +804,10 @@ template <class T> using UniquePersistent = Global<T>; /** - * Trait specifying behavior of |TracedGlobal<T>|. + * Deprecated. Use |TracedReference<T>| instead. */ 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; -}; +struct TracedGlobalTrait {}; /** * A traced handle with copy and move semantics. The handle is to be used @@ -821,15 +820,131 @@ struct TracedGlobalTrait { * |v8::EmbedderHeapTracer::IsRootForNonTracingGC()| whether the handle should * be treated as root or not. * - * For destruction semantics see |TracedGlobalTrait<T>|. + * Note that the base class cannot be instantiated itself. Choose from + * - TracedGlobal + * - TracedReference */ template <typename T> -class TracedGlobal { +class TracedReferenceBase { public: /** + * Returns true if this TracedReferenceBase is empty, i.e., has not been + * assigned an object. + */ + bool IsEmpty() const { return val_ == nullptr; } + + /** + * If non-empty, destroy the underlying storage cell. |IsEmpty| will return + * true after this call. + */ + V8_INLINE void Reset(); + + /** + * Construct a Local<T> from this handle. + */ + Local<T> Get(Isolate* isolate) const { return Local<T>::New(isolate, *this); } + + template <class S> + V8_INLINE bool operator==(const TracedReferenceBase<S>& that) const { + internal::Address* a = reinterpret_cast<internal::Address*>(val_); + internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); + if (a == nullptr) return b == nullptr; + if (b == nullptr) return false; + return *a == *b; + } + + template <class S> + V8_INLINE bool operator==(const Local<S>& that) const { + internal::Address* a = reinterpret_cast<internal::Address*>(val_); + internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); + if (a == nullptr) return b == nullptr; + if (b == nullptr) return false; + return *a == *b; + } + + template <class S> + V8_INLINE bool operator!=(const TracedReferenceBase<S>& that) const { + return !operator==(that); + } + + template <class S> + V8_INLINE bool operator!=(const Local<S>& that) const { + return !operator==(that); + } + + /** + * Assigns a wrapper class ID to the handle. + */ + V8_INLINE void SetWrapperClassId(uint16_t class_id); + + /** + * Returns the class ID previously assigned to this handle or 0 if no class ID + * was previously assigned. + */ + V8_INLINE uint16_t WrapperClassId() const; + + /** + * Adds a finalization callback to the handle. The type of this callback is + * similar to WeakCallbackType::kInternalFields, i.e., it will pass the + * parameter and the first two internal fields of the object. + * + * The callback is then supposed to reset the handle in the callback. No + * further V8 API may be called in this callback. In case additional work + * involving V8 needs to be done, a second callback can be scheduled using + * WeakCallbackInfo<void>::SetSecondPassCallback. + */ + V8_INLINE void SetFinalizationCallback( + void* parameter, WeakCallbackInfo<void>::Callback callback); + + template <class S> + V8_INLINE TracedReferenceBase<S>& As() const { + return reinterpret_cast<TracedReferenceBase<S>&>( + const_cast<TracedReferenceBase<T>&>(*this)); + } + + private: + enum DestructionMode { kWithDestructor, kWithoutDestructor }; + + /** + * An empty TracedReferenceBase without storage cell. + */ + TracedReferenceBase() = default; + + V8_INLINE static T* New(Isolate* isolate, T* that, void* slot, + DestructionMode destruction_mode); + + T* val_ = nullptr; + + friend class EmbedderHeapTracer; + template <typename F> + friend class Local; + friend class Object; + template <typename F> + friend class TracedGlobal; + template <typename F> + friend class TracedReference; + template <typename F> + friend class ReturnValue; +}; + +/** + * A traced handle with destructor that clears the handle. For more details see + * TracedReferenceBase. + */ +template <typename T> +class TracedGlobal : public TracedReferenceBase<T> { + public: + using TracedReferenceBase<T>::Reset; + + /** + * Destructor resetting the handle. + */ + ~TracedGlobal() { this->Reset(); } + + /** * An empty TracedGlobal without storage cell. */ - TracedGlobal() = default; + TracedGlobal() : TracedReferenceBase<T>() {} /** * Construct a TracedGlobal from a Local. @@ -838,8 +953,9 @@ class TracedGlobal { * pointing to the same object. */ template <class S> - TracedGlobal(Isolate* isolate, Local<S> that) - : val_(New(isolate, *that, &val_)) { + TracedGlobal(Isolate* isolate, Local<S> that) : TracedReferenceBase<T>() { + this->val_ = this->New(isolate, that.val_, &this->val_, + TracedReferenceBase<T>::kWithDestructor); TYPE_CHECK(T, S); } @@ -906,121 +1022,126 @@ class TracedGlobal { V8_INLINE TracedGlobal& operator=(const TracedGlobal<S>& rhs); /** - * Returns true if this TracedGlobal is empty, i.e., has not been assigned an - * object. - */ - bool IsEmpty() const { return val_ == nullptr; } - - /** - * If non-empty, destroy the underlying storage cell. |IsEmpty| will return - * true after this call. - */ - V8_INLINE void Reset(); - - /** * If non-empty, destroy the underlying storage cell and create a new one with * the contents of other if other is non empty */ template <class S> V8_INLINE void Reset(Isolate* isolate, const Local<S>& other); - /** - * Construct a Local<T> from this handle. - */ - Local<T> Get(Isolate* isolate) const { return Local<T>::New(isolate, *this); } - template <class S> V8_INLINE TracedGlobal<S>& As() const { return reinterpret_cast<TracedGlobal<S>&>( const_cast<TracedGlobal<T>&>(*this)); } +}; - template <class S> - V8_INLINE bool operator==(const TracedGlobal<S>& that) const { - 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; - } +/** + * A traced handle without destructor that clears the handle. The embedder needs + * to ensure that the handle is not accessed once the V8 object has been + * reclaimed. This can happen when the handle is not passed through the + * EmbedderHeapTracer. For more details see TracedReferenceBase. + */ +template <typename T> +class TracedReference : public TracedReferenceBase<T> { + public: + using TracedReferenceBase<T>::Reset; + /** + * An empty TracedReference without storage cell. + */ + TracedReference() : TracedReferenceBase<T>() {} + + /** + * Construct a TracedReference from a Local. + * + * When the Local is non-empty, a new storage cell is created + * pointing to the same object. + */ template <class S> - V8_INLINE bool operator==(const Local<S>& that) const { - 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; + TracedReference(Isolate* isolate, Local<S> that) : TracedReferenceBase<T>() { + this->val_ = this->New(isolate, that.val_, &this->val_, + TracedReferenceBase<T>::kWithoutDestructor); + TYPE_CHECK(T, S); } - template <class S> - V8_INLINE bool operator!=(const TracedGlobal<S>& that) const { - return !operator==(that); + /** + * Move constructor initializing TracedReference from an + * existing one. + */ + V8_INLINE TracedReference(TracedReference&& other) { + // Forward to operator=. + *this = std::move(other); } - template <class S> - V8_INLINE bool operator!=(const Local<S>& that) const { - return !operator==(that); + /** + * Move constructor initializing TracedReference from an + * existing one. + */ + template <typename S> + V8_INLINE TracedReference(TracedReference<S>&& other) { + // Forward to operator=. + *this = std::move(other); } /** - * Assigns a wrapper class ID to the handle. + * Copy constructor initializing TracedReference from an + * existing one. */ - V8_INLINE void SetWrapperClassId(uint16_t class_id); + V8_INLINE TracedReference(const TracedReference& other) { + // Forward to operator=; + *this = other; + } /** - * Returns the class ID previously assigned to this handle or 0 if no class ID - * was previously assigned. + * Copy constructor initializing TracedReference from an + * existing one. */ - V8_INLINE uint16_t WrapperClassId() const; + template <typename S> + V8_INLINE TracedReference(const TracedReference<S>& other) { + // Forward to operator=; + *this = other; + } /** - * Adds a finalization callback to the handle. The type of this callback is - * similar to WeakCallbackType::kInternalFields, i.e., it will pass the - * parameter and the first two internal fields of the object. - * - * The callback is then supposed to reset the handle in the callback. No - * further V8 API may be called in this callback. In case additional work - * involving V8 needs to be done, a second callback can be scheduled using - * WeakCallbackInfo<void>::SetSecondPassCallback. + * Move assignment operator initializing TracedGlobal from an existing one. */ - V8_INLINE void SetFinalizationCallback( - void* parameter, WeakCallbackInfo<void>::Callback callback); + V8_INLINE TracedReference& operator=(TracedReference&& rhs); - private: - // 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; - } - }; + /** + * Move assignment operator initializing TracedGlobal from an existing one. + */ + template <class S> + V8_INLINE TracedReference& operator=(TracedReference<S>&& rhs); - V8_INLINE static T* New(Isolate* isolate, T* that, void* slot); + /** + * Copy assignment operator initializing TracedGlobal from an existing one. + * + * Note: Prohibited when |other| has a finalization callback set through + * |SetFinalizationCallback|. + */ + V8_INLINE TracedReference& operator=(const TracedReference& rhs); - T* operator*() const { return this->val_; } + /** + * Copy assignment operator initializing TracedGlobal from an existing one. + * + * Note: Prohibited when |other| has a finalization callback set through + * |SetFinalizationCallback|. + */ + template <class S> + V8_INLINE TracedReference& operator=(const TracedReference<S>& rhs); - typename std::conditional< - TracedGlobalTrait<TracedGlobal<T>>::kRequiresExplicitDestruction, - WrappedForDestruction, T*>::type val_{nullptr}; + /** + * If non-empty, destroy the underlying storage cell and create a new one with + * the contents of other if other is non empty + */ + template <class S> + V8_INLINE void Reset(Isolate* isolate, const Local<S>& other); - friend class EmbedderHeapTracer; - template <typename F> - friend class Local; - friend class Object; - template <typename F> - friend class ReturnValue; + template <class S> + V8_INLINE TracedReference<S>& As() const { + return reinterpret_cast<TracedReference<S>&>( + const_cast<TracedReference<T>&>(*this)); + } }; /** @@ -1154,9 +1275,8 @@ class V8_EXPORT SealHandleScope { // --- Special objects --- - /** - * The superclass of values and API object templates. + * The superclass of objects that can reside on V8's heap. */ class V8_EXPORT Data { private: @@ -1303,7 +1423,7 @@ class V8_EXPORT UnboundScript { /** * A compiled JavaScript module, not yet tied to a Context. */ -class V8_EXPORT UnboundModuleScript { +class V8_EXPORT UnboundModuleScript : public Data { // Only used as a container for code caching. }; @@ -1326,7 +1446,7 @@ class V8_EXPORT Location { /** * A compiled JavaScript module. */ -class V8_EXPORT Module { +class V8_EXPORT Module : public Data { public: /** * The different states a module can be in. @@ -1440,19 +1560,11 @@ class V8_EXPORT Module { /** * Set this module's exported value for the name export_name to the specified * export_value. This method must be called only on Modules created via - * CreateSyntheticModule. An error will be thrown if export_name is not one - * of the export_names that were passed in that CreateSyntheticModule call. - * Returns Just(true) on success, Nothing<bool>() if an error was thrown. + * CreateSyntheticModule. export_name must be one of the export_names that + * were passed in that CreateSyntheticModule call. */ - V8_WARN_UNUSED_RESULT Maybe<bool> SetSyntheticModuleExport( - Isolate* isolate, Local<String> export_name, Local<Value> export_value); - V8_DEPRECATE_SOON( - "Use the preceding SetSyntheticModuleExport with an Isolate parameter, " - "instead of the one that follows. The former will throw a runtime " - "error if called for an export that doesn't exist (as per spec); " - "the latter will crash with a failed CHECK().", - void SetSyntheticModuleExport(Local<String> export_name, - Local<Value> export_value)); + void SetSyntheticModuleExport(Local<String> export_name, + Local<Value> export_value); }; /** @@ -1628,8 +1740,8 @@ class V8_EXPORT ScriptCompiler { V8_DEPRECATE_SOON( "This class takes ownership of source_stream, so use the constructor " - "taking a unique_ptr to make these semantics clearer", - StreamedSource(ExternalSourceStream* source_stream, Encoding encoding)); + "taking a unique_ptr to make these semantics clearer") + StreamedSource(ExternalSourceStream* source_stream, Encoding encoding); StreamedSource(std::unique_ptr<ExternalSourceStream> source_stream, Encoding encoding); ~StreamedSource(); @@ -3405,7 +3517,7 @@ enum class IndexFilter { kIncludeIndices, kSkipIndices }; * kConvertToString will convert integer indices to strings. * kKeepNumbers will return numbers for integer indices. */ -enum class KeyConversionMode { kConvertToString, kKeepNumbers }; +enum class KeyConversionMode { kConvertToString, kKeepNumbers, kNoNumbers }; /** * Integrity level for objects. @@ -3649,8 +3761,9 @@ class V8_EXPORT Object : public Value { return object.val_->InternalFieldCount(); } - /** Same as above, but works for TracedGlobal. */ - V8_INLINE static int InternalFieldCount(const TracedGlobal<Object>& object) { + /** Same as above, but works for TracedReferenceBase. */ + V8_INLINE static int InternalFieldCount( + const TracedReferenceBase<Object>& object) { return object.val_->InternalFieldCount(); } @@ -3675,7 +3788,7 @@ class V8_EXPORT Object : public Value { /** Same as above, but works for TracedGlobal. */ V8_INLINE static void* GetAlignedPointerFromInternalField( - const TracedGlobal<Object>& object, int index) { + const TracedReferenceBase<Object>& object, int index) { return object.val_->GetAlignedPointerFromInternalField(index); } @@ -3965,7 +4078,7 @@ class ReturnValue { template <typename S> V8_INLINE void Set(const Global<S>& handle); template <typename S> - V8_INLINE void Set(const TracedGlobal<S>& handle); + V8_INLINE void Set(const TracedReferenceBase<S>& handle); template <typename S> V8_INLINE void Set(const Local<S> handle); // Fast primitive setters @@ -4521,48 +4634,39 @@ class V8_EXPORT CompiledWasmModule { // An instance of WebAssembly.Module. class V8_EXPORT WasmModuleObject : public Object { public: + WasmModuleObject() = delete; + /** * An opaque, native heap object for transferring wasm modules. It * supports move semantics, and does not support copy semantics. - * TODO(wasm): Merge this with CompiledWasmModule once code sharing is always - * enabled. */ - class TransferrableModule final { - public: - TransferrableModule(TransferrableModule&& src) = default; - TransferrableModule(const TransferrableModule& src) = delete; - - TransferrableModule& operator=(TransferrableModule&& src) = default; - TransferrableModule& operator=(const TransferrableModule& src) = delete; - - private: - typedef std::shared_ptr<internal::wasm::NativeModule> SharedModule; - friend class WasmModuleObject; - explicit TransferrableModule(SharedModule shared_module) - : shared_module_(std::move(shared_module)) {} - TransferrableModule(OwnedBuffer serialized, OwnedBuffer bytes) - : serialized_(std::move(serialized)), wire_bytes_(std::move(bytes)) {} - - SharedModule shared_module_; - OwnedBuffer serialized_ = {nullptr, 0}; - OwnedBuffer wire_bytes_ = {nullptr, 0}; - }; + using TransferrableModule V8_DEPRECATED("Use CompiledWasmModule directly") = + CompiledWasmModule; /** * Get an in-memory, non-persistable, and context-independent (meaning, * suitable for transfer to another Isolate and Context) representation * of this wasm compiled module. */ + V8_DEPRECATED("Use GetCompiledModule") TransferrableModule GetTransferrableModule(); /** * Efficiently re-create a WasmModuleObject, without recompiling, from * a TransferrableModule. */ + V8_DEPRECATED("Use FromCompiledModule") static MaybeLocal<WasmModuleObject> FromTransferrableModule( Isolate* isolate, const TransferrableModule&); /** + * Efficiently re-create a WasmModuleObject, without recompiling, from + * a CompiledWasmModule. + */ + static MaybeLocal<WasmModuleObject> FromCompiledModule( + Isolate* isolate, const CompiledWasmModule&); + + /** * Get the compiled module for this module object. The compiled module can be * shared by several module objects. */ @@ -4584,11 +4688,7 @@ class V8_EXPORT WasmModuleObject : public Object { static MaybeLocal<WasmModuleObject> Compile(Isolate* isolate, const uint8_t* start, size_t length); - static MemorySpan<const uint8_t> AsReference(const OwnedBuffer& buff) { - return {buff.buffer.get(), buff.size}; - } - WasmModuleObject(); static void CheckCast(Value* obj); }; @@ -4720,6 +4820,33 @@ class V8_EXPORT WasmModuleObjectBuilderStreaming final { enum class ArrayBufferCreationMode { kInternalized, kExternalized }; +/** + * A wrapper around the backing store (i.e. the raw memory) of an array buffer. + * + * The allocation and destruction of backing stores is generally managed by + * V8. Clients should always use standard C++ memory ownership types (i.e. + * std::unique_ptr and std::shared_ptr) to manage lifetimes of backing stores + * properly, since V8 internal objects may alias backing stores. + */ +class V8_EXPORT BackingStore : public v8::internal::BackingStoreBase { + public: + ~BackingStore(); + + /** + * Return a pointer to the beginning of the memory block for this backing + * store. The pointer is only valid as long as this backing store object + * lives. + */ + void* Data() const; + + /** + * The length (in bytes) of this backing store. + */ + size_t ByteLength() const; + + private: + BackingStore(); +}; /** * An instance of the built-in ArrayBuffer constructor (ES6 draft 15.13.5). @@ -4857,6 +4984,21 @@ class V8_EXPORT ArrayBuffer : public Object { ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized); /** + * Create a new ArrayBuffer with an existing backing store. + * The created array keeps a reference to the backing store until the array + * is garbage collected. Note that the IsExternal bit does not affect this + * reference from the array to the backing store. + * + * In future IsExternal bit will be removed. Until then the bit is set as + * follows. If the backing store does not own the underlying buffer, then + * the array is created in externalized state. Otherwise, the array is created + * in internalized state. In the latter case the array can be transitioned + * to the externalized state using Externalize(backing_store). + */ + static Local<ArrayBuffer> New(Isolate* isolate, + std::shared_ptr<BackingStore> backing_store); + + /** * Returns true if ArrayBuffer is externalized, that is, does not * own its memory block. */ @@ -4867,12 +5009,6 @@ class V8_EXPORT ArrayBuffer : public Object { */ bool IsDetachable() const; - // TODO(913887): fix the use of 'neuter' in the API. - V8_DEPRECATED("Use IsDetachable() instead.", - inline bool IsNeuterable() const) { - return IsDetachable(); - } - /** * Detaches this ArrayBuffer and all its views (typed arrays). * Detaching sets the byte length of the buffer and all typed arrays to zero, @@ -4881,9 +5017,6 @@ class V8_EXPORT ArrayBuffer : public Object { */ void Detach(); - // TODO(913887): fix the use of 'neuter' in the API. - V8_DEPRECATED("Use Detach() instead.", inline void Neuter()) { Detach(); } - /** * Make this ArrayBuffer external. The pointer to underlying memory block * and byte length are returned as |Contents| structure. After ArrayBuffer @@ -4892,11 +5025,20 @@ class V8_EXPORT ArrayBuffer : public Object { * * The Data pointer of ArrayBuffer::Contents must be freed using the provided * deleter, which will call ArrayBuffer::Allocator::Free if the buffer - * was allocated with ArraryBuffer::Allocator::Allocate. + * was allocated with ArrayBuffer::Allocator::Allocate. */ Contents Externalize(); /** + * Marks this ArrayBuffer external given a witness that the embedder + * has fetched the backing store using the new GetBackingStore() function. + * + * With the new lifetime management of backing stores there is no need for + * externalizing, so this function exists only to make the transition easier. + */ + void Externalize(const std::shared_ptr<BackingStore>& backing_store); + + /** * Get a pointer to the ArrayBuffer's underlying memory block without * externalizing it. If the ArrayBuffer is not externalized, this pointer * will become invalid as soon as the ArrayBuffer gets garbage collected. @@ -4906,6 +5048,16 @@ class V8_EXPORT ArrayBuffer : public Object { */ Contents GetContents(); + /** + * Get a shared pointer to the backing store of this array buffer. This + * pointer coordinates the lifetime management of the internal storage + * with any live ArrayBuffers on the heap, even across isolates. The embedder + * should not attempt to manage lifetime of the storage through other means. + * + * This function replaces both Externalize() and GetContents(). + */ + std::shared_ptr<BackingStore> GetBackingStore(); + V8_INLINE static ArrayBuffer* Cast(Value* obj); static const int kInternalFieldCount = V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT; @@ -4914,6 +5066,7 @@ class V8_EXPORT ArrayBuffer : public Object { private: ArrayBuffer(); static void CheckCast(Value* obj); + Contents GetContents(bool externalize); }; @@ -5281,14 +5434,28 @@ class V8_EXPORT SharedArrayBuffer : public Object { ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized); /** + * Create a new SharedArrayBuffer with an existing backing store. + * The created array keeps a reference to the backing store until the array + * is garbage collected. Note that the IsExternal bit does not affect this + * reference from the array to the backing store. + * + * In future IsExternal bit will be removed. Until then the bit is set as + * follows. If the backing store does not own the underlying buffer, then + * the array is created in externalized state. Otherwise, the array is created + * in internalized state. In the latter case the array can be transitioned + * to the externalized state using Externalize(backing_store). + */ + static Local<SharedArrayBuffer> New( + Isolate* isolate, std::shared_ptr<BackingStore> backing_store); + + /** * Create a new SharedArrayBuffer over an existing memory block. Propagate * flags to indicate whether the underlying buffer can be grown. */ - V8_DEPRECATED("Use New method with data, and byte_length instead.", - static Local<SharedArrayBuffer> New( - Isolate* isolate, const SharedArrayBuffer::Contents&, - ArrayBufferCreationMode mode = - ArrayBufferCreationMode::kExternalized)); + V8_DEPRECATED("Use New method with data, and byte_length instead.") + static Local<SharedArrayBuffer> New( + Isolate* isolate, const SharedArrayBuffer::Contents&, + ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized); /** * Returns true if SharedArrayBuffer is externalized, that is, does not @@ -5311,6 +5478,15 @@ class V8_EXPORT SharedArrayBuffer : public Object { Contents Externalize(); /** + * Marks this SharedArrayBuffer external given a witness that the embedder + * has fetched the backing store using the new GetBackingStore() function. + * + * With the new lifetime management of backing stores there is no need for + * externalizing, so this function exists only to make the transition easier. + */ + void Externalize(const std::shared_ptr<BackingStore>& backing_store); + + /** * Get a pointer to the ArrayBuffer's underlying memory block without * externalizing it. If the ArrayBuffer is not externalized, this pointer * will become invalid as soon as the ArrayBuffer became garbage collected. @@ -5324,6 +5500,16 @@ class V8_EXPORT SharedArrayBuffer : public Object { */ Contents GetContents(); + /** + * Get a shared pointer to the backing store of this array buffer. This + * pointer coordinates the lifetime management of the internal storage + * with any live ArrayBuffers on the heap, even across isolates. The embedder + * should not attempt to manage lifetime of the storage through other means. + * + * This function replaces both Externalize() and GetContents(). + */ + std::shared_ptr<BackingStore> GetBackingStore(); + V8_INLINE static SharedArrayBuffer* Cast(Value* obj); static const int kInternalFieldCount = V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT; @@ -5331,6 +5517,7 @@ class V8_EXPORT SharedArrayBuffer : public Object { private: SharedArrayBuffer(); static void CheckCast(Value* obj); + Contents GetContents(bool externalize); }; @@ -6655,34 +6842,26 @@ class V8_EXPORT ResourceConstraints { /** * Deprecated functions. Do not use in new code. */ - V8_DEPRECATE_SOON("Use code_range_size_in_bytes.", - size_t code_range_size() const) { - return code_range_size_ / kMB; - } - V8_DEPRECATE_SOON("Use set_code_range_size_in_bytes.", - void set_code_range_size(size_t limit_in_mb)) { + V8_DEPRECATE_SOON("Use code_range_size_in_bytes.") + size_t code_range_size() const { return code_range_size_ / kMB; } + V8_DEPRECATE_SOON("Use set_code_range_size_in_bytes.") + void set_code_range_size(size_t limit_in_mb) { code_range_size_ = limit_in_mb * kMB; } - V8_DEPRECATE_SOON("Use max_young_generation_size_in_bytes.", - size_t max_semi_space_size_in_kb() const); - V8_DEPRECATE_SOON("Use set_max_young_generation_size_in_bytes.", - void set_max_semi_space_size_in_kb(size_t limit_in_kb)); - V8_DEPRECATE_SOON("Use max_old_generation_size_in_bytes.", - size_t max_old_space_size() const) { - return max_old_generation_size_ / kMB; - } - V8_DEPRECATE_SOON("Use set_max_old_generation_size_in_bytes.", - void set_max_old_space_size(size_t limit_in_mb)) { + V8_DEPRECATE_SOON("Use max_young_generation_size_in_bytes.") + size_t max_semi_space_size_in_kb() const; + V8_DEPRECATE_SOON("Use set_max_young_generation_size_in_bytes.") + void set_max_semi_space_size_in_kb(size_t limit_in_kb); + V8_DEPRECATE_SOON("Use max_old_generation_size_in_bytes.") + size_t max_old_space_size() const { return max_old_generation_size_ / kMB; } + V8_DEPRECATE_SOON("Use set_max_old_generation_size_in_bytes.") + void set_max_old_space_size(size_t limit_in_mb) { max_old_generation_size_ = limit_in_mb * kMB; } - V8_DEPRECATE_SOON("Zone does not pool memory any more.", - size_t max_zone_pool_size() const) { - return max_zone_pool_size_; - } - V8_DEPRECATE_SOON("Zone does not pool memory any more.", - void set_max_zone_pool_size(size_t bytes)) { - max_zone_pool_size_ = bytes; - } + V8_DEPRECATE_SOON("Zone does not pool memory any more.") + size_t max_zone_pool_size() const { return max_zone_pool_size_; } + V8_DEPRECATE_SOON("Zone does not pool memory any more.") + void set_max_zone_pool_size(size_t bytes) { max_zone_pool_size_ = bytes; } private: static constexpr size_t kMB = 1048576u; @@ -6756,6 +6935,7 @@ enum class CrashKeyId { kReadonlySpaceFirstPageAddress, kMapSpaceFirstPageAddress, kCodeSpaceFirstPageAddress, + kDumpType, }; typedef void (*AddCrashKeyCallback)(CrashKeyId id, const std::string& value); @@ -6875,6 +7055,7 @@ class PromiseRejectMessage { typedef void (*PromiseRejectCallback)(PromiseRejectMessage message); // --- Microtasks Callbacks --- +V8_DEPRECATE_SOON("Use *WithData version.") typedef void (*MicrotasksCompletedCallback)(Isolate*); typedef void (*MicrotasksCompletedCallbackWithData)(Isolate*, void*); typedef void (*MicrotaskCallback)(void* data); @@ -7384,7 +7565,8 @@ class V8_EXPORT EmbedderHeapTracer { class V8_EXPORT TracedGlobalHandleVisitor { public: virtual ~TracedGlobalHandleVisitor() = default; - virtual void VisitTracedGlobalHandle(const TracedGlobal<Value>& value) = 0; + virtual void VisitTracedGlobalHandle(const TracedGlobal<Value>& handle) {} + virtual void VisitTracedReference(const TracedReference<Value>& handle) {} }; /** @@ -7422,13 +7604,14 @@ class V8_EXPORT EmbedderHeapTracer { virtual void RegisterV8References( const std::vector<std::pair<void*, void*> >& embedder_fields) = 0; - void RegisterEmbedderReference(const TracedGlobal<v8::Value>& ref); + V8_DEPRECATE_SOON("Use version taking TracedReferenceBase<v8::Data> argument") + void RegisterEmbedderReference(const TracedReferenceBase<v8::Value>& ref); + void RegisterEmbedderReference(const TracedReferenceBase<v8::Data>& ref); /** * Called at the beginning of a GC cycle. */ - V8_DEPRECATED("Use version with flags.", virtual void TracePrologue()) {} - virtual void TracePrologue(TraceFlags flags); + virtual void TracePrologue(TraceFlags flags) {} /** * Called to advance tracing in the embedder. @@ -7455,8 +7638,7 @@ class V8_EXPORT EmbedderHeapTracer { * overriden to fill a |TraceSummary| that is used by V8 to schedule future * garbage collections. */ - V8_DEPRECATE_SOON("Use version with parameter.", - virtual void TraceEpilogue()) {} + V8_DEPRECATED("Use version with parameter.") virtual void TraceEpilogue() {} virtual void TraceEpilogue(TraceSummary* trace_summary); /** @@ -7483,32 +7665,35 @@ class V8_EXPORT EmbedderHeapTracer { * * 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|. + * - No action is required if handles are used with destructors, i.e., by just + * using |TracedGlobal|. + * - When run without destructors, i.e., by using + * |TracedReference|, V8 calls |ResetHandleInNonTracingGC|. * - * 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. + * Note that the |handle| is different from the handle that the embedder holds + * for retaining the object. The embedder may use |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; - } + const v8::TracedReference<v8::Value>& handle); + virtual bool IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value>& handle); /** * 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. + * Note that the |handle| is different from the handle that the embedder holds + * for retaining the object. It is up to the embedder to find the original + * handle via the object or class id. */ virtual void ResetHandleInNonTracingGC( - const v8::TracedGlobal<v8::Value>& handle) {} + const v8::TracedReference<v8::Value>& handle); + V8_DEPRECATE_SOON( + "Use TracedReference version when not requiring destructors.") + virtual void ResetHandleInNonTracingGC( + const v8::TracedGlobal<v8::Value>& handle); /* * Called by the embedder to immediately perform a full garbage collection. @@ -7575,6 +7760,8 @@ struct DeserializeInternalFieldsCallback { }; typedef DeserializeInternalFieldsCallback DeserializeEmbedderFieldsCallback; +enum class MeasureMemoryMode { kSummary, kDetailed }; + /** * Isolate represents an isolated instance of the V8 engine. V8 isolates have * completely separate states. Objects from one isolate must not be used in @@ -8096,6 +8283,17 @@ class V8_EXPORT Isolate { bool GetHeapCodeAndMetadataStatistics(HeapCodeStatistics* object_statistics); /** + * Enqueues a memory measurement request for the given context and mode. + * This API is experimental and may change significantly. + * + * \param mode Indicates whether the result should include per-context + * memory usage or just the total memory usage. + * \returns a promise that will be resolved with memory usage estimate. + */ + v8::MaybeLocal<v8::Promise> MeasureMemory(v8::Local<v8::Context> context, + MeasureMemoryMode mode); + + /** * Get a call stack sample from the isolate. * \param state Execution state. * \param frames Caller allocated buffer to store stack frames. @@ -8156,8 +8354,8 @@ class V8_EXPORT Isolate { Local<Context> GetCurrentContext(); /** Returns the last context entered through V8's C++ API. */ - V8_DEPRECATED("Use GetEnteredOrMicrotaskContext().", - Local<Context> GetEnteredContext()); + V8_DEPRECATED("Use GetEnteredOrMicrotaskContext().") + Local<Context> GetEnteredContext(); /** * Returns either the last context entered through V8's C++ API, or the @@ -8469,18 +8667,16 @@ class V8_EXPORT Isolate { * Executing scripts inside the callback will not re-trigger microtasks and * the callback. */ - V8_DEPRECATE_SOON("Use *WithData version.", - void AddMicrotasksCompletedCallback( - MicrotasksCompletedCallback callback)); + V8_DEPRECATE_SOON("Use *WithData version.") + void AddMicrotasksCompletedCallback(MicrotasksCompletedCallback callback); void AddMicrotasksCompletedCallback( MicrotasksCompletedCallbackWithData callback, void* data = nullptr); /** * Removes callback that was installed by AddMicrotasksCompletedCallback. */ - V8_DEPRECATE_SOON("Use *WithData version.", - void RemoveMicrotasksCompletedCallback( - MicrotasksCompletedCallback callback)); + V8_DEPRECATE_SOON("Use *WithData version.") + void RemoveMicrotasksCompletedCallback(MicrotasksCompletedCallback callback); void RemoveMicrotasksCompletedCallback( MicrotasksCompletedCallbackWithData callback, void* data = nullptr); @@ -8910,6 +9106,7 @@ class V8_EXPORT V8 { * handled entirely on the embedders' side. * - The call will abort if the data is invalid. */ + V8_DEPRECATED("The natives blob is deprecated (https://crbug.com/v8/7624).") static void SetNativesDataBlob(StartupData* startup_blob); static void SetSnapshotDataBlob(StartupData* startup_blob); @@ -8922,8 +9119,6 @@ class V8_EXPORT V8 { */ static void SetFlagsFromString(const char* str); static void SetFlagsFromString(const char* str, size_t length); - V8_DEPRECATED("use size_t version", - static void SetFlagsFromString(const char* str, int length)); /** * Sets V8 flags from the command line. @@ -9006,8 +9201,11 @@ class V8_EXPORT V8 { * not perform any file IO. */ static void InitializeExternalStartupData(const char* directory_path); + V8_DEPRECATED("The natives blob is deprecated (https://crbug.com/v8/7624).") static void InitializeExternalStartupData(const char* natives_blob, const char* snapshot_blob); + static void InitializeExternalStartupDataFromFile(const char* snapshot_blob); + /** * Sets the v8::Platform to use. This should be invoked before V8 is * initialized. @@ -9040,9 +9238,8 @@ class V8_EXPORT V8 { * \param context The third argument passed to the Linux signal handler, which * points to a ucontext_t structure. */ - V8_DEPRECATE_SOON("Use TryHandleWebAssemblyTrapPosix", - static bool TryHandleSignal(int signal_number, void* info, - void* context)); + V8_DEPRECATE_SOON("Use TryHandleWebAssemblyTrapPosix") + static bool TryHandleSignal(int signal_number, void* info, void* context); #endif // V8_OS_POSIX /** @@ -9111,8 +9308,12 @@ class V8_EXPORT V8 { template <class T> friend class Maybe; template <class T> + friend class TracedReferenceBase; + template <class T> friend class TracedGlobal; template <class T> + friend class TracedReference; + template <class T> friend class WeakCallbackInfo; template <class T> friend class Eternal; template <class T> friend class PersistentBase; @@ -9983,7 +10184,7 @@ Local<T> Local<T>::New(Isolate* isolate, const PersistentBase<T>& that) { } template <class T> -Local<T> Local<T>::New(Isolate* isolate, const TracedGlobal<T>& that) { +Local<T> Local<T>::New(Isolate* isolate, const TracedReferenceBase<T>& that) { return New(isolate, that.val_); } @@ -10164,26 +10365,20 @@ Global<T>& Global<T>::operator=(Global<S>&& rhs) { } template <class T> -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) { +T* TracedReferenceBase<T>::New(Isolate* isolate, T* that, void* slot, + DestructionMode destruction_mode) { 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), - TracedGlobalTrait<TracedGlobal<T>>::kRequiresExplicitDestruction)); + destruction_mode == kWithDestructor)); } template <class T> -void TracedGlobal<T>::Reset() { +void TracedReferenceBase<T>::Reset() { if (IsEmpty()) return; - V8::DisposeTracedGlobal(reinterpret_cast<internal::Address*>(**this)); + V8::DisposeTracedGlobal(reinterpret_cast<internal::Address*>(val_)); val_ = nullptr; } @@ -10193,7 +10388,8 @@ void TracedGlobal<T>::Reset(Isolate* isolate, const Local<S>& other) { TYPE_CHECK(T, S); Reset(); if (other.IsEmpty()) return; - this->val_ = New(isolate, other.val_, &val_); + this->val_ = this->New(isolate, other.val_, &this->val_, + TracedReferenceBase<T>::kWithDestructor); } template <class T> @@ -10241,28 +10437,83 @@ TracedGlobal<T>& TracedGlobal<T>::operator=(const TracedGlobal& rhs) { } template <class T> -void TracedGlobal<T>::SetWrapperClassId(uint16_t class_id) { +template <class S> +void TracedReference<T>::Reset(Isolate* isolate, const Local<S>& other) { + TYPE_CHECK(T, S); + Reset(); + if (other.IsEmpty()) return; + this->val_ = this->New(isolate, other.val_, &this->val_, + TracedReferenceBase<T>::kWithoutDestructor); +} + +template <class T> +template <class S> +TracedReference<T>& TracedReference<T>::operator=(TracedReference<S>&& rhs) { + TYPE_CHECK(T, S); + *this = std::move(rhs.template As<T>()); + return *this; +} + +template <class T> +template <class S> +TracedReference<T>& TracedReference<T>::operator=( + const TracedReference<S>& rhs) { + TYPE_CHECK(T, S); + *this = rhs.template As<T>(); + return *this; +} + +template <class T> +TracedReference<T>& TracedReference<T>::operator=(TracedReference&& rhs) { + if (this != &rhs) { + this->Reset(); + if (rhs.val_ != nullptr) { + this->val_ = rhs.val_; + V8::MoveTracedGlobalReference( + reinterpret_cast<internal::Address**>(&rhs.val_), + reinterpret_cast<internal::Address**>(&this->val_)); + rhs.val_ = nullptr; + } + } + return *this; +} + +template <class T> +TracedReference<T>& TracedReference<T>::operator=(const TracedReference& 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 TracedReferenceBase<T>::SetWrapperClassId(uint16_t class_id) { typedef internal::Internals I; if (IsEmpty()) return; - internal::Address* obj = reinterpret_cast<internal::Address*>(**this); + internal::Address* obj = reinterpret_cast<internal::Address*>(val_); uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; *reinterpret_cast<uint16_t*>(addr) = class_id; } template <class T> -uint16_t TracedGlobal<T>::WrapperClassId() const { +uint16_t TracedReferenceBase<T>::WrapperClassId() const { typedef internal::Internals I; if (IsEmpty()) return 0; - internal::Address* obj = reinterpret_cast<internal::Address*>(**this); + internal::Address* obj = reinterpret_cast<internal::Address*>(val_); uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; return *reinterpret_cast<uint16_t*>(addr); } template <class T> -void TracedGlobal<T>::SetFinalizationCallback( +void TracedReferenceBase<T>::SetFinalizationCallback( void* parameter, typename WeakCallbackInfo<void>::Callback callback) { - V8::SetFinalizationCallbackTraced( - reinterpret_cast<internal::Address*>(**this), parameter, callback); + V8::SetFinalizationCallbackTraced(reinterpret_cast<internal::Address*>(val_), + parameter, callback); } template <typename T> @@ -10281,12 +10532,12 @@ void ReturnValue<T>::Set(const Global<S>& handle) { template <typename T> template <typename S> -void ReturnValue<T>::Set(const TracedGlobal<S>& handle) { +void ReturnValue<T>::Set(const TracedReferenceBase<S>& handle) { TYPE_CHECK(T, S); if (V8_UNLIKELY(handle.IsEmpty())) { *value_ = GetDefaultValue(); } else { - *value_ = *reinterpret_cast<internal::Address*>(*handle); + *value_ = *reinterpret_cast<internal::Address*>(handle.val_); } } |