11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_OBJECTS_JS_ARRAY_BUFFER_H_ 61cb0ef41Sopenharmony_ci#define V8_OBJECTS_JS_ARRAY_BUFFER_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "include/v8-typed-array.h" 91cb0ef41Sopenharmony_ci#include "src/objects/backing-store.h" 101cb0ef41Sopenharmony_ci#include "src/objects/js-objects.h" 111cb0ef41Sopenharmony_ci#include "torque-generated/bit-fields.h" 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci// Has to be the last include (doesn't have include guards): 141cb0ef41Sopenharmony_ci#include "src/objects/object-macros.h" 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_cinamespace v8 { 171cb0ef41Sopenharmony_cinamespace internal { 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ciclass ArrayBufferExtension; 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci#include "torque-generated/src/objects/js-array-buffer-tq.inc" 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ciclass JSArrayBuffer 241cb0ef41Sopenharmony_ci : public TorqueGeneratedJSArrayBuffer<JSArrayBuffer, 251cb0ef41Sopenharmony_ci JSObjectWithEmbedderSlots> { 261cb0ef41Sopenharmony_ci public: 271cb0ef41Sopenharmony_ci// The maximum length for JSArrayBuffer's supported by V8. 281cb0ef41Sopenharmony_ci// On 32-bit architectures we limit this to 2GiB, so that 291cb0ef41Sopenharmony_ci// we can continue to use CheckBounds with the Unsigned31 301cb0ef41Sopenharmony_ci// restriction for the length. 311cb0ef41Sopenharmony_ci#if V8_HOST_ARCH_32_BIT 321cb0ef41Sopenharmony_ci static constexpr size_t kMaxByteLength = kMaxInt; 331cb0ef41Sopenharmony_ci#else 341cb0ef41Sopenharmony_ci static constexpr size_t kMaxByteLength = kMaxSafeInteger; 351cb0ef41Sopenharmony_ci#endif 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci // [byte_length]: length in bytes 381cb0ef41Sopenharmony_ci DECL_PRIMITIVE_ACCESSORS(byte_length, size_t) 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci // [backing_store]: backing memory for this array 411cb0ef41Sopenharmony_ci // It should not be assumed that this will be nullptr for empty ArrayBuffers. 421cb0ef41Sopenharmony_ci DECL_GETTER(backing_store, void*) 431cb0ef41Sopenharmony_ci inline void set_backing_store(Isolate* isolate, void* value); 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci // [extension]: extension object used for GC 461cb0ef41Sopenharmony_ci DECL_PRIMITIVE_ACCESSORS(extension, ArrayBufferExtension*) 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci // [bit_field]: boolean flags 491cb0ef41Sopenharmony_ci DECL_PRIMITIVE_ACCESSORS(bit_field, uint32_t) 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci // Clear uninitialized padding space. This ensures that the snapshot content 521cb0ef41Sopenharmony_ci // is deterministic. Depending on the V8 build mode there could be no padding. 531cb0ef41Sopenharmony_ci V8_INLINE void clear_padding(); 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci // Bit positions for [bit_field]. 561cb0ef41Sopenharmony_ci DEFINE_TORQUE_GENERATED_JS_ARRAY_BUFFER_FLAGS() 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci // [is_external]: true indicates that the embedder is in charge of freeing the 591cb0ef41Sopenharmony_ci // backing_store, while is_external == false means that v8 will free the 601cb0ef41Sopenharmony_ci // memory block once all ArrayBuffers referencing it are collected by the GC. 611cb0ef41Sopenharmony_ci DECL_BOOLEAN_ACCESSORS(is_external) 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci // [is_detachable]: false => this buffer cannot be detached. 641cb0ef41Sopenharmony_ci DECL_BOOLEAN_ACCESSORS(is_detachable) 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci // [was_detached]: true => the buffer was previously detached. 671cb0ef41Sopenharmony_ci DECL_BOOLEAN_ACCESSORS(was_detached) 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci // [is_asmjs_memory]: true => this buffer was once used as asm.js memory. 701cb0ef41Sopenharmony_ci DECL_BOOLEAN_ACCESSORS(is_asmjs_memory) 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci // [is_shared]: true if this is a SharedArrayBuffer or a 731cb0ef41Sopenharmony_ci // GrowableSharedArrayBuffer. 741cb0ef41Sopenharmony_ci DECL_BOOLEAN_ACCESSORS(is_shared) 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci // [is_resizable]: true if this is a ResizableArrayBuffer or a 771cb0ef41Sopenharmony_ci // GrowableSharedArrayBuffer. 781cb0ef41Sopenharmony_ci DECL_BOOLEAN_ACCESSORS(is_resizable) 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci // An ArrayBuffer is empty if its BackingStore is empty or if there is none. 811cb0ef41Sopenharmony_ci // An empty ArrayBuffer will have a byte_length of zero but not necessarily a 821cb0ef41Sopenharmony_ci // nullptr backing_store. An ArrayBuffer with a byte_length of zero may not 831cb0ef41Sopenharmony_ci // necessarily be empty though, as it may be a GrowableSharedArrayBuffer. 841cb0ef41Sopenharmony_ci // An ArrayBuffer with a size greater than zero is never empty. 851cb0ef41Sopenharmony_ci DECL_GETTER(IsEmpty, bool) 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci // Initializes the fields of the ArrayBuffer. The provided backing_store can 881cb0ef41Sopenharmony_ci // be nullptr. If it is not nullptr, then the function registers it with 891cb0ef41Sopenharmony_ci // src/heap/array-buffer-tracker.h. 901cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE void Setup(SharedFlag shared, ResizableFlag resizable, 911cb0ef41Sopenharmony_ci std::shared_ptr<BackingStore> backing_store); 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci // Attaches the backing store to an already constructed empty ArrayBuffer. 941cb0ef41Sopenharmony_ci // This is intended to be used only in ArrayBufferConstructor builtin. 951cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE void Attach(std::shared_ptr<BackingStore> backing_store); 961cb0ef41Sopenharmony_ci // Detach the backing store from this array buffer if it is detachable. 971cb0ef41Sopenharmony_ci // This sets the internal pointer and length to 0 and unregisters the backing 981cb0ef41Sopenharmony_ci // store from the array buffer tracker. If the array buffer is not detachable, 991cb0ef41Sopenharmony_ci // this is a nop. 1001cb0ef41Sopenharmony_ci // 1011cb0ef41Sopenharmony_ci // Array buffers that wrap wasm memory objects are special in that they 1021cb0ef41Sopenharmony_ci // are normally not detachable, but can become detached as a side effect 1031cb0ef41Sopenharmony_ci // of growing the underlying memory object. The {force_for_wasm_memory} flag 1041cb0ef41Sopenharmony_ci // is used by the implementation of Wasm memory growth in order to bypass the 1051cb0ef41Sopenharmony_ci // non-detachable check. 1061cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE void Detach(bool force_for_wasm_memory = false); 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci // Get a reference to backing store of this array buffer, if there is a 1091cb0ef41Sopenharmony_ci // backing store. Returns nullptr if there is no backing store (e.g. detached 1101cb0ef41Sopenharmony_ci // or a zero-length array buffer). 1111cb0ef41Sopenharmony_ci inline std::shared_ptr<BackingStore> GetBackingStore() const; 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci inline size_t GetByteLength() const; 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci static size_t GsabByteLength(Isolate* isolate, Address raw_array_buffer); 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci static Maybe<bool> GetResizableBackingStorePageConfiguration( 1181cb0ef41Sopenharmony_ci Isolate* isolate, size_t byte_length, size_t max_byte_length, 1191cb0ef41Sopenharmony_ci ShouldThrow should_throw, size_t* page_size, size_t* initial_pages, 1201cb0ef41Sopenharmony_ci size_t* max_pages); 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci // Allocates an ArrayBufferExtension for this array buffer, unless it is 1231cb0ef41Sopenharmony_ci // already associated with an extension. 1241cb0ef41Sopenharmony_ci ArrayBufferExtension* EnsureExtension(); 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci // Frees the associated ArrayBufferExtension and returns its backing store. 1271cb0ef41Sopenharmony_ci std::shared_ptr<BackingStore> RemoveExtension(); 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci // Marks ArrayBufferExtension 1301cb0ef41Sopenharmony_ci void MarkExtension(); 1311cb0ef41Sopenharmony_ci void YoungMarkExtension(); 1321cb0ef41Sopenharmony_ci void YoungMarkExtensionPromoted(); 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci // 1351cb0ef41Sopenharmony_ci // Serializer/deserializer support. 1361cb0ef41Sopenharmony_ci // 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci // Backing stores are serialized/deserialized separately. During serialization 1391cb0ef41Sopenharmony_ci // the backing store reference is stored in the backing store field and upon 1401cb0ef41Sopenharmony_ci // deserialization it is converted back to actual external (off-heap) pointer 1411cb0ef41Sopenharmony_ci // value. 1421cb0ef41Sopenharmony_ci inline uint32_t GetBackingStoreRefForDeserialization() const; 1431cb0ef41Sopenharmony_ci inline void SetBackingStoreRefForSerialization(uint32_t ref); 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_ci // Dispatched behavior. 1461cb0ef41Sopenharmony_ci DECL_PRINTER(JSArrayBuffer) 1471cb0ef41Sopenharmony_ci DECL_VERIFIER(JSArrayBuffer) 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci static constexpr int kEndOfTaggedFieldsOffset = JSObject::kHeaderSize; 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci static const int kSizeWithEmbedderFields = 1521cb0ef41Sopenharmony_ci kHeaderSize + 1531cb0ef41Sopenharmony_ci v8::ArrayBuffer::kEmbedderFieldCount * kEmbedderDataSlotSize; 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci class BodyDescriptor; 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci private: 1581cb0ef41Sopenharmony_ci inline ArrayBufferExtension** extension_location() const; 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_ci#if V8_COMPRESS_POINTERS 1611cb0ef41Sopenharmony_ci static const int kUninitializedTagMask = 1; 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci inline uint32_t* extension_lo() const; 1641cb0ef41Sopenharmony_ci inline uint32_t* extension_hi() const; 1651cb0ef41Sopenharmony_ci#endif 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci TQ_OBJECT_CONSTRUCTORS(JSArrayBuffer) 1681cb0ef41Sopenharmony_ci}; 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci// Each JSArrayBuffer (with a backing store) has a corresponding native-heap 1711cb0ef41Sopenharmony_ci// allocated ArrayBufferExtension for GC purposes and storing the backing store. 1721cb0ef41Sopenharmony_ci// When marking a JSArrayBuffer, the GC also marks the native 1731cb0ef41Sopenharmony_ci// extension-object. The GC periodically iterates all extensions concurrently 1741cb0ef41Sopenharmony_ci// and frees unmarked ones. 1751cb0ef41Sopenharmony_ci// https://docs.google.com/document/d/1-ZrLdlFX1nXT3z-FAgLbKal1gI8Auiaya_My-a0UJ28/edit 1761cb0ef41Sopenharmony_ciclass ArrayBufferExtension final : public Malloced { 1771cb0ef41Sopenharmony_ci public: 1781cb0ef41Sopenharmony_ci ArrayBufferExtension() : backing_store_(std::shared_ptr<BackingStore>()) {} 1791cb0ef41Sopenharmony_ci explicit ArrayBufferExtension(std::shared_ptr<BackingStore> backing_store) 1801cb0ef41Sopenharmony_ci : backing_store_(backing_store) {} 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci void Mark() { marked_.store(true, std::memory_order_relaxed); } 1831cb0ef41Sopenharmony_ci void Unmark() { marked_.store(false, std::memory_order_relaxed); } 1841cb0ef41Sopenharmony_ci bool IsMarked() const { return marked_.load(std::memory_order_relaxed); } 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci void YoungMark() { set_young_gc_state(GcState::Copied); } 1871cb0ef41Sopenharmony_ci void YoungMarkPromoted() { set_young_gc_state(GcState::Promoted); } 1881cb0ef41Sopenharmony_ci void YoungUnmark() { set_young_gc_state(GcState::Dead); } 1891cb0ef41Sopenharmony_ci bool IsYoungMarked() const { return young_gc_state() != GcState::Dead; } 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ci bool IsYoungPromoted() const { return young_gc_state() == GcState::Promoted; } 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_ci std::shared_ptr<BackingStore> backing_store() { return backing_store_; } 1941cb0ef41Sopenharmony_ci BackingStore* backing_store_raw() { return backing_store_.get(); } 1951cb0ef41Sopenharmony_ci 1961cb0ef41Sopenharmony_ci size_t accounting_length() const { 1971cb0ef41Sopenharmony_ci return accounting_length_.load(std::memory_order_relaxed); 1981cb0ef41Sopenharmony_ci } 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ci void set_accounting_length(size_t accounting_length) { 2011cb0ef41Sopenharmony_ci accounting_length_.store(accounting_length, std::memory_order_relaxed); 2021cb0ef41Sopenharmony_ci } 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ci size_t ClearAccountingLength() { 2051cb0ef41Sopenharmony_ci return accounting_length_.exchange(0, std::memory_order_relaxed); 2061cb0ef41Sopenharmony_ci } 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ci std::shared_ptr<BackingStore> RemoveBackingStore() { 2091cb0ef41Sopenharmony_ci return std::move(backing_store_); 2101cb0ef41Sopenharmony_ci } 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_ci void set_backing_store(std::shared_ptr<BackingStore> backing_store) { 2131cb0ef41Sopenharmony_ci backing_store_ = std::move(backing_store); 2141cb0ef41Sopenharmony_ci } 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci void reset_backing_store() { backing_store_.reset(); } 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ci ArrayBufferExtension* next() const { return next_; } 2191cb0ef41Sopenharmony_ci void set_next(ArrayBufferExtension* extension) { next_ = extension; } 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ci private: 2221cb0ef41Sopenharmony_ci enum class GcState : uint8_t { Dead = 0, Copied, Promoted }; 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ci std::atomic<bool> marked_{false}; 2251cb0ef41Sopenharmony_ci std::atomic<GcState> young_gc_state_{GcState::Dead}; 2261cb0ef41Sopenharmony_ci std::shared_ptr<BackingStore> backing_store_; 2271cb0ef41Sopenharmony_ci ArrayBufferExtension* next_ = nullptr; 2281cb0ef41Sopenharmony_ci std::atomic<size_t> accounting_length_{0}; 2291cb0ef41Sopenharmony_ci 2301cb0ef41Sopenharmony_ci GcState young_gc_state() const { 2311cb0ef41Sopenharmony_ci return young_gc_state_.load(std::memory_order_relaxed); 2321cb0ef41Sopenharmony_ci } 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_ci void set_young_gc_state(GcState value) { 2351cb0ef41Sopenharmony_ci young_gc_state_.store(value, std::memory_order_relaxed); 2361cb0ef41Sopenharmony_ci } 2371cb0ef41Sopenharmony_ci}; 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ciclass JSArrayBufferView 2401cb0ef41Sopenharmony_ci : public TorqueGeneratedJSArrayBufferView<JSArrayBufferView, 2411cb0ef41Sopenharmony_ci JSObjectWithEmbedderSlots> { 2421cb0ef41Sopenharmony_ci public: 2431cb0ef41Sopenharmony_ci // [byte_offset]: offset of typed array in bytes. 2441cb0ef41Sopenharmony_ci DECL_PRIMITIVE_ACCESSORS(byte_offset, size_t) 2451cb0ef41Sopenharmony_ci 2461cb0ef41Sopenharmony_ci // [byte_length]: length of typed array in bytes. 2471cb0ef41Sopenharmony_ci DECL_PRIMITIVE_ACCESSORS(byte_length, size_t) 2481cb0ef41Sopenharmony_ci 2491cb0ef41Sopenharmony_ci DECL_VERIFIER(JSArrayBufferView) 2501cb0ef41Sopenharmony_ci 2511cb0ef41Sopenharmony_ci // Bit positions for [bit_field]. 2521cb0ef41Sopenharmony_ci DEFINE_TORQUE_GENERATED_JS_ARRAY_BUFFER_VIEW_FLAGS() 2531cb0ef41Sopenharmony_ci 2541cb0ef41Sopenharmony_ci inline bool WasDetached() const; 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci DECL_BOOLEAN_ACCESSORS(is_length_tracking) 2571cb0ef41Sopenharmony_ci DECL_BOOLEAN_ACCESSORS(is_backed_by_rab) 2581cb0ef41Sopenharmony_ci inline bool IsVariableLength() const; 2591cb0ef41Sopenharmony_ci 2601cb0ef41Sopenharmony_ci static constexpr int kEndOfTaggedFieldsOffset = kByteOffsetOffset; 2611cb0ef41Sopenharmony_ci 2621cb0ef41Sopenharmony_ci STATIC_ASSERT(IsAligned(kByteOffsetOffset, kUIntptrSize)); 2631cb0ef41Sopenharmony_ci STATIC_ASSERT(IsAligned(kByteLengthOffset, kUIntptrSize)); 2641cb0ef41Sopenharmony_ci 2651cb0ef41Sopenharmony_ci TQ_OBJECT_CONSTRUCTORS(JSArrayBufferView) 2661cb0ef41Sopenharmony_ci}; 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ciclass JSTypedArray 2691cb0ef41Sopenharmony_ci : public TorqueGeneratedJSTypedArray<JSTypedArray, JSArrayBufferView> { 2701cb0ef41Sopenharmony_ci public: 2711cb0ef41Sopenharmony_ci // TODO(v8:4153): This should be equal to JSArrayBuffer::kMaxByteLength 2721cb0ef41Sopenharmony_ci // eventually. 2731cb0ef41Sopenharmony_ci static constexpr size_t kMaxLength = v8::TypedArray::kMaxLength; 2741cb0ef41Sopenharmony_ci 2751cb0ef41Sopenharmony_ci // [length]: length of typed array in elements. 2761cb0ef41Sopenharmony_ci DECL_PRIMITIVE_GETTER(length, size_t) 2771cb0ef41Sopenharmony_ci 2781cb0ef41Sopenharmony_ci DECL_GETTER(base_pointer, Object) 2791cb0ef41Sopenharmony_ci DECL_ACQUIRE_GETTER(base_pointer, Object) 2801cb0ef41Sopenharmony_ci 2811cb0ef41Sopenharmony_ci // ES6 9.4.5.3 2821cb0ef41Sopenharmony_ci V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty( 2831cb0ef41Sopenharmony_ci Isolate* isolate, Handle<JSTypedArray> o, Handle<Object> key, 2841cb0ef41Sopenharmony_ci PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw); 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ci ExternalArrayType type(); 2871cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE size_t element_size() const; 2881cb0ef41Sopenharmony_ci 2891cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE Handle<JSArrayBuffer> GetBuffer(); 2901cb0ef41Sopenharmony_ci 2911cb0ef41Sopenharmony_ci // The `DataPtr` is `base_ptr + external_pointer`, and `base_ptr` is nullptr 2921cb0ef41Sopenharmony_ci // for off-heap typed arrays. 2931cb0ef41Sopenharmony_ci static constexpr bool kOffHeapDataPtrEqualsExternalPointer = true; 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci // Use with care: returns raw pointer into heap. 2961cb0ef41Sopenharmony_ci inline void* DataPtr(); 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_ci inline void SetOffHeapDataPtr(Isolate* isolate, void* base, Address offset); 2991cb0ef41Sopenharmony_ci 3001cb0ef41Sopenharmony_ci // Whether the buffer's backing store is on-heap or off-heap. 3011cb0ef41Sopenharmony_ci inline bool is_on_heap() const; 3021cb0ef41Sopenharmony_ci inline bool is_on_heap(AcquireLoadTag tag) const; 3031cb0ef41Sopenharmony_ci 3041cb0ef41Sopenharmony_ci // Only valid to call when IsVariableLength() is true. 3051cb0ef41Sopenharmony_ci size_t GetVariableLengthOrOutOfBounds(bool& out_of_bounds) const; 3061cb0ef41Sopenharmony_ci 3071cb0ef41Sopenharmony_ci inline size_t GetLengthOrOutOfBounds(bool& out_of_bounds) const; 3081cb0ef41Sopenharmony_ci inline size_t GetLength() const; 3091cb0ef41Sopenharmony_ci inline size_t GetByteLength() const; 3101cb0ef41Sopenharmony_ci inline bool IsOutOfBounds() const; 3111cb0ef41Sopenharmony_ci inline bool IsDetachedOrOutOfBounds() const; 3121cb0ef41Sopenharmony_ci 3131cb0ef41Sopenharmony_ci static size_t LengthTrackingGsabBackedTypedArrayLength(Isolate* isolate, 3141cb0ef41Sopenharmony_ci Address raw_array); 3151cb0ef41Sopenharmony_ci 3161cb0ef41Sopenharmony_ci // Note: this is a pointer compression specific optimization. 3171cb0ef41Sopenharmony_ci // Normally, on-heap typed arrays contain HeapObject value in |base_pointer| 3181cb0ef41Sopenharmony_ci // field and an offset in |external_pointer|. 3191cb0ef41Sopenharmony_ci // When pointer compression is enabled we want to combine decompression with 3201cb0ef41Sopenharmony_ci // the offset addition. In order to do that we add an isolate root to the 3211cb0ef41Sopenharmony_ci // |external_pointer| value and therefore the data pointer computation can 3221cb0ef41Sopenharmony_ci // is a simple addition of a (potentially sign-extended) |base_pointer| loaded 3231cb0ef41Sopenharmony_ci // as Tagged_t value and an |external_pointer| value. 3241cb0ef41Sopenharmony_ci // For full-pointer mode the compensation value is zero. 3251cb0ef41Sopenharmony_ci static inline Address ExternalPointerCompensationForOnHeapArray( 3261cb0ef41Sopenharmony_ci PtrComprCageBase cage_base); 3271cb0ef41Sopenharmony_ci 3281cb0ef41Sopenharmony_ci // 3291cb0ef41Sopenharmony_ci // Serializer/deserializer support. 3301cb0ef41Sopenharmony_ci // 3311cb0ef41Sopenharmony_ci 3321cb0ef41Sopenharmony_ci // External backing stores are serialized/deserialized separately. 3331cb0ef41Sopenharmony_ci // During serialization the backing store reference is stored in the typed 3341cb0ef41Sopenharmony_ci // array object and upon deserialization it is converted back to actual 3351cb0ef41Sopenharmony_ci // external (off-heap) pointer value. 3361cb0ef41Sopenharmony_ci // The backing store reference is stored in the external_pointer field. 3371cb0ef41Sopenharmony_ci inline uint32_t GetExternalBackingStoreRefForDeserialization() const; 3381cb0ef41Sopenharmony_ci inline void SetExternalBackingStoreRefForSerialization(uint32_t ref); 3391cb0ef41Sopenharmony_ci 3401cb0ef41Sopenharmony_ci // Subtracts external pointer compensation from the external pointer value. 3411cb0ef41Sopenharmony_ci inline void RemoveExternalPointerCompensationForSerialization( 3421cb0ef41Sopenharmony_ci Isolate* isolate); 3431cb0ef41Sopenharmony_ci // Adds external pointer compensation to the external pointer value. 3441cb0ef41Sopenharmony_ci inline void AddExternalPointerCompensationForDeserialization( 3451cb0ef41Sopenharmony_ci Isolate* isolate); 3461cb0ef41Sopenharmony_ci 3471cb0ef41Sopenharmony_ci static inline MaybeHandle<JSTypedArray> Validate(Isolate* isolate, 3481cb0ef41Sopenharmony_ci Handle<Object> receiver, 3491cb0ef41Sopenharmony_ci const char* method_name); 3501cb0ef41Sopenharmony_ci 3511cb0ef41Sopenharmony_ci // Dispatched behavior. 3521cb0ef41Sopenharmony_ci DECL_PRINTER(JSTypedArray) 3531cb0ef41Sopenharmony_ci DECL_VERIFIER(JSTypedArray) 3541cb0ef41Sopenharmony_ci 3551cb0ef41Sopenharmony_ci // TODO(v8:9287): Re-enable when GCMole stops mixing 32/64 bit configs. 3561cb0ef41Sopenharmony_ci // STATIC_ASSERT(IsAligned(kLengthOffset, kTaggedSize)); 3571cb0ef41Sopenharmony_ci // STATIC_ASSERT(IsAligned(kExternalPointerOffset, kTaggedSize)); 3581cb0ef41Sopenharmony_ci 3591cb0ef41Sopenharmony_ci static const int kSizeWithEmbedderFields = 3601cb0ef41Sopenharmony_ci kHeaderSize + 3611cb0ef41Sopenharmony_ci v8::ArrayBufferView::kEmbedderFieldCount * kEmbedderDataSlotSize; 3621cb0ef41Sopenharmony_ci 3631cb0ef41Sopenharmony_ci class BodyDescriptor; 3641cb0ef41Sopenharmony_ci 3651cb0ef41Sopenharmony_ci#ifdef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP 3661cb0ef41Sopenharmony_ci static constexpr size_t kMaxSizeInHeap = V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP; 3671cb0ef41Sopenharmony_ci#else 3681cb0ef41Sopenharmony_ci static constexpr size_t kMaxSizeInHeap = 64; 3691cb0ef41Sopenharmony_ci#endif 3701cb0ef41Sopenharmony_ci 3711cb0ef41Sopenharmony_ci private: 3721cb0ef41Sopenharmony_ci template <typename IsolateT> 3731cb0ef41Sopenharmony_ci friend class Deserializer; 3741cb0ef41Sopenharmony_ci friend class Factory; 3751cb0ef41Sopenharmony_ci 3761cb0ef41Sopenharmony_ci DECL_PRIMITIVE_SETTER(length, size_t) 3771cb0ef41Sopenharmony_ci // Reads the "length" field, doesn't assert the TypedArray is not RAB / GSAB 3781cb0ef41Sopenharmony_ci // backed. 3791cb0ef41Sopenharmony_ci inline size_t LengthUnchecked() const; 3801cb0ef41Sopenharmony_ci 3811cb0ef41Sopenharmony_ci DECL_GETTER(external_pointer, Address) 3821cb0ef41Sopenharmony_ci 3831cb0ef41Sopenharmony_ci DECL_SETTER(base_pointer, Object) 3841cb0ef41Sopenharmony_ci DECL_RELEASE_SETTER(base_pointer, Object) 3851cb0ef41Sopenharmony_ci 3861cb0ef41Sopenharmony_ci inline void set_external_pointer(Isolate* isolate, Address value); 3871cb0ef41Sopenharmony_ci 3881cb0ef41Sopenharmony_ci TQ_OBJECT_CONSTRUCTORS(JSTypedArray) 3891cb0ef41Sopenharmony_ci}; 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ciclass JSDataView 3921cb0ef41Sopenharmony_ci : public TorqueGeneratedJSDataView<JSDataView, JSArrayBufferView> { 3931cb0ef41Sopenharmony_ci public: 3941cb0ef41Sopenharmony_ci // [data_pointer]: pointer to the actual data. 3951cb0ef41Sopenharmony_ci DECL_GETTER(data_pointer, void*) 3961cb0ef41Sopenharmony_ci inline void set_data_pointer(Isolate* isolate, void* value); 3971cb0ef41Sopenharmony_ci 3981cb0ef41Sopenharmony_ci // Dispatched behavior. 3991cb0ef41Sopenharmony_ci DECL_PRINTER(JSDataView) 4001cb0ef41Sopenharmony_ci DECL_VERIFIER(JSDataView) 4011cb0ef41Sopenharmony_ci 4021cb0ef41Sopenharmony_ci // TODO(v8:9287): Re-enable when GCMole stops mixing 32/64 bit configs. 4031cb0ef41Sopenharmony_ci // STATIC_ASSERT(IsAligned(kDataPointerOffset, kTaggedSize)); 4041cb0ef41Sopenharmony_ci 4051cb0ef41Sopenharmony_ci static const int kSizeWithEmbedderFields = 4061cb0ef41Sopenharmony_ci kHeaderSize + 4071cb0ef41Sopenharmony_ci v8::ArrayBufferView::kEmbedderFieldCount * kEmbedderDataSlotSize; 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci class BodyDescriptor; 4101cb0ef41Sopenharmony_ci 4111cb0ef41Sopenharmony_ci TQ_OBJECT_CONSTRUCTORS(JSDataView) 4121cb0ef41Sopenharmony_ci}; 4131cb0ef41Sopenharmony_ci 4141cb0ef41Sopenharmony_ci} // namespace internal 4151cb0ef41Sopenharmony_ci} // namespace v8 4161cb0ef41Sopenharmony_ci 4171cb0ef41Sopenharmony_ci#include "src/objects/object-macros-undef.h" 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_ci#endif // V8_OBJECTS_JS_ARRAY_BUFFER_H_ 420