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