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_INL_H_
61cb0ef41Sopenharmony_ci#define V8_OBJECTS_JS_ARRAY_BUFFER_INL_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/heap/heap-write-barrier-inl.h"
91cb0ef41Sopenharmony_ci#include "src/objects/js-array-buffer.h"
101cb0ef41Sopenharmony_ci#include "src/objects/js-objects-inl.h"
111cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.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_ci#include "torque-generated/src/objects/js-array-buffer-tq-inl.inc"
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ciTQ_OBJECT_CONSTRUCTORS_IMPL(JSArrayBuffer)
221cb0ef41Sopenharmony_ciTQ_OBJECT_CONSTRUCTORS_IMPL(JSArrayBufferView)
231cb0ef41Sopenharmony_ciTQ_OBJECT_CONSTRUCTORS_IMPL(JSTypedArray)
241cb0ef41Sopenharmony_ciTQ_OBJECT_CONSTRUCTORS_IMPL(JSDataView)
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ciACCESSORS(JSTypedArray, base_pointer, Object, kBasePointerOffset)
271cb0ef41Sopenharmony_ciRELEASE_ACQUIRE_ACCESSORS(JSTypedArray, base_pointer, Object,
281cb0ef41Sopenharmony_ci                          kBasePointerOffset)
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_cisize_t JSArrayBuffer::byte_length() const {
311cb0ef41Sopenharmony_ci  return ReadField<size_t>(kByteLengthOffset);
321cb0ef41Sopenharmony_ci}
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_civoid JSArrayBuffer::set_byte_length(size_t value) {
351cb0ef41Sopenharmony_ci  WriteField<size_t>(kByteLengthOffset, value);
361cb0ef41Sopenharmony_ci}
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ciDEF_GETTER(JSArrayBuffer, backing_store, void*) {
391cb0ef41Sopenharmony_ci  Address value = ReadSandboxedPointerField(kBackingStoreOffset, cage_base);
401cb0ef41Sopenharmony_ci  return reinterpret_cast<void*>(value);
411cb0ef41Sopenharmony_ci}
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_civoid JSArrayBuffer::set_backing_store(Isolate* isolate, void* value) {
441cb0ef41Sopenharmony_ci  Address addr = reinterpret_cast<Address>(value);
451cb0ef41Sopenharmony_ci  WriteSandboxedPointerField(kBackingStoreOffset, isolate, addr);
461cb0ef41Sopenharmony_ci}
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_cistd::shared_ptr<BackingStore> JSArrayBuffer::GetBackingStore() const {
491cb0ef41Sopenharmony_ci  if (!extension()) return nullptr;
501cb0ef41Sopenharmony_ci  return extension()->backing_store();
511cb0ef41Sopenharmony_ci}
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_cisize_t JSArrayBuffer::GetByteLength() const {
541cb0ef41Sopenharmony_ci  if V8_UNLIKELY (is_shared() && is_resizable()) {
551cb0ef41Sopenharmony_ci    // Invariant: byte_length for GSAB is 0 (it needs to be read from the
561cb0ef41Sopenharmony_ci    // BackingStore).
571cb0ef41Sopenharmony_ci    DCHECK_EQ(0, byte_length());
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci    return GetBackingStore()->byte_length(std::memory_order_seq_cst);
601cb0ef41Sopenharmony_ci  }
611cb0ef41Sopenharmony_ci  return byte_length();
621cb0ef41Sopenharmony_ci}
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ciuint32_t JSArrayBuffer::GetBackingStoreRefForDeserialization() const {
651cb0ef41Sopenharmony_ci  return static_cast<uint32_t>(ReadField<Address>(kBackingStoreOffset));
661cb0ef41Sopenharmony_ci}
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_civoid JSArrayBuffer::SetBackingStoreRefForSerialization(uint32_t ref) {
691cb0ef41Sopenharmony_ci  WriteField<Address>(kBackingStoreOffset, static_cast<Address>(ref));
701cb0ef41Sopenharmony_ci}
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ciArrayBufferExtension* JSArrayBuffer::extension() const {
731cb0ef41Sopenharmony_ci#if V8_COMPRESS_POINTERS
741cb0ef41Sopenharmony_ci    // With pointer compression the extension-field might not be
751cb0ef41Sopenharmony_ci    // pointer-aligned. However on ARM64 this field needs to be aligned to
761cb0ef41Sopenharmony_ci    // perform atomic operations on it. Therefore we split the pointer into two
771cb0ef41Sopenharmony_ci    // 32-bit words that we update atomically. We don't have an ABA problem here
781cb0ef41Sopenharmony_ci    // since there can never be an Attach() after Detach() (transitions only
791cb0ef41Sopenharmony_ci    // from NULL --> some ptr --> NULL).
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci    // Synchronize with publishing release store of non-null extension
821cb0ef41Sopenharmony_ci    uint32_t lo = base::AsAtomic32::Acquire_Load(extension_lo());
831cb0ef41Sopenharmony_ci    if (lo & kUninitializedTagMask) return nullptr;
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci    // Synchronize with release store of null extension
861cb0ef41Sopenharmony_ci    uint32_t hi = base::AsAtomic32::Acquire_Load(extension_hi());
871cb0ef41Sopenharmony_ci    uint32_t verify_lo = base::AsAtomic32::Relaxed_Load(extension_lo());
881cb0ef41Sopenharmony_ci    if (lo != verify_lo) return nullptr;
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci    uintptr_t address = static_cast<uintptr_t>(lo);
911cb0ef41Sopenharmony_ci    address |= static_cast<uintptr_t>(hi) << 32;
921cb0ef41Sopenharmony_ci    return reinterpret_cast<ArrayBufferExtension*>(address);
931cb0ef41Sopenharmony_ci#else
941cb0ef41Sopenharmony_ci    return base::AsAtomicPointer::Acquire_Load(extension_location());
951cb0ef41Sopenharmony_ci#endif
961cb0ef41Sopenharmony_ci}
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_civoid JSArrayBuffer::set_extension(ArrayBufferExtension* extension) {
991cb0ef41Sopenharmony_ci#if V8_COMPRESS_POINTERS
1001cb0ef41Sopenharmony_ci    if (extension != nullptr) {
1011cb0ef41Sopenharmony_ci      uintptr_t address = reinterpret_cast<uintptr_t>(extension);
1021cb0ef41Sopenharmony_ci      base::AsAtomic32::Relaxed_Store(extension_hi(),
1031cb0ef41Sopenharmony_ci                                      static_cast<uint32_t>(address >> 32));
1041cb0ef41Sopenharmony_ci      base::AsAtomic32::Release_Store(extension_lo(),
1051cb0ef41Sopenharmony_ci                                      static_cast<uint32_t>(address));
1061cb0ef41Sopenharmony_ci    } else {
1071cb0ef41Sopenharmony_ci      base::AsAtomic32::Relaxed_Store(extension_lo(),
1081cb0ef41Sopenharmony_ci                                      0 | kUninitializedTagMask);
1091cb0ef41Sopenharmony_ci      base::AsAtomic32::Release_Store(extension_hi(), 0);
1101cb0ef41Sopenharmony_ci    }
1111cb0ef41Sopenharmony_ci#else
1121cb0ef41Sopenharmony_ci    base::AsAtomicPointer::Release_Store(extension_location(), extension);
1131cb0ef41Sopenharmony_ci#endif
1141cb0ef41Sopenharmony_ci    WriteBarrier::Marking(*this, extension);
1151cb0ef41Sopenharmony_ci}
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ciArrayBufferExtension** JSArrayBuffer::extension_location() const {
1181cb0ef41Sopenharmony_ci  Address location = field_address(kExtensionOffset);
1191cb0ef41Sopenharmony_ci  return reinterpret_cast<ArrayBufferExtension**>(location);
1201cb0ef41Sopenharmony_ci}
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci#if V8_COMPRESS_POINTERS
1231cb0ef41Sopenharmony_ciuint32_t* JSArrayBuffer::extension_lo() const {
1241cb0ef41Sopenharmony_ci  Address location = field_address(kExtensionOffset);
1251cb0ef41Sopenharmony_ci  return reinterpret_cast<uint32_t*>(location);
1261cb0ef41Sopenharmony_ci}
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ciuint32_t* JSArrayBuffer::extension_hi() const {
1291cb0ef41Sopenharmony_ci  Address location = field_address(kExtensionOffset) + sizeof(uint32_t);
1301cb0ef41Sopenharmony_ci  return reinterpret_cast<uint32_t*>(location);
1311cb0ef41Sopenharmony_ci}
1321cb0ef41Sopenharmony_ci#endif
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_civoid JSArrayBuffer::clear_padding() {
1351cb0ef41Sopenharmony_ci  if (FIELD_SIZE(kOptionalPaddingOffset) != 0) {
1361cb0ef41Sopenharmony_ci    DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset));
1371cb0ef41Sopenharmony_ci    memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0,
1381cb0ef41Sopenharmony_ci           FIELD_SIZE(kOptionalPaddingOffset));
1391cb0ef41Sopenharmony_ci  }
1401cb0ef41Sopenharmony_ci}
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_civoid JSArrayBuffer::set_bit_field(uint32_t bits) {
1431cb0ef41Sopenharmony_ci  RELAXED_WRITE_UINT32_FIELD(*this, kBitFieldOffset, bits);
1441cb0ef41Sopenharmony_ci}
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ciuint32_t JSArrayBuffer::bit_field() const {
1471cb0ef41Sopenharmony_ci  return RELAXED_READ_UINT32_FIELD(*this, kBitFieldOffset);
1481cb0ef41Sopenharmony_ci}
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ci// |bit_field| fields.
1511cb0ef41Sopenharmony_ciBIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_external,
1521cb0ef41Sopenharmony_ci                    JSArrayBuffer::IsExternalBit)
1531cb0ef41Sopenharmony_ciBIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_detachable,
1541cb0ef41Sopenharmony_ci                    JSArrayBuffer::IsDetachableBit)
1551cb0ef41Sopenharmony_ciBIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, was_detached,
1561cb0ef41Sopenharmony_ci                    JSArrayBuffer::WasDetachedBit)
1571cb0ef41Sopenharmony_ciBIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_asmjs_memory,
1581cb0ef41Sopenharmony_ci                    JSArrayBuffer::IsAsmJsMemoryBit)
1591cb0ef41Sopenharmony_ciBIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_shared,
1601cb0ef41Sopenharmony_ci                    JSArrayBuffer::IsSharedBit)
1611cb0ef41Sopenharmony_ciBIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_resizable,
1621cb0ef41Sopenharmony_ci                    JSArrayBuffer::IsResizableBit)
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_cibool JSArrayBuffer::IsEmpty() const {
1651cb0ef41Sopenharmony_ci  auto backing_store = GetBackingStore();
1661cb0ef41Sopenharmony_ci  bool is_empty = !backing_store || backing_store->IsEmpty();
1671cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(is_empty, byte_length() == 0);
1681cb0ef41Sopenharmony_ci  return is_empty;
1691cb0ef41Sopenharmony_ci}
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_cisize_t JSArrayBufferView::byte_offset() const {
1721cb0ef41Sopenharmony_ci  return ReadField<size_t>(kByteOffsetOffset);
1731cb0ef41Sopenharmony_ci}
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_civoid JSArrayBufferView::set_byte_offset(size_t value) {
1761cb0ef41Sopenharmony_ci  WriteField<size_t>(kByteOffsetOffset, value);
1771cb0ef41Sopenharmony_ci}
1781cb0ef41Sopenharmony_ci
1791cb0ef41Sopenharmony_cisize_t JSArrayBufferView::byte_length() const {
1801cb0ef41Sopenharmony_ci  return ReadField<size_t>(kByteLengthOffset);
1811cb0ef41Sopenharmony_ci}
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_civoid JSArrayBufferView::set_byte_length(size_t value) {
1841cb0ef41Sopenharmony_ci  WriteField<size_t>(kByteLengthOffset, value);
1851cb0ef41Sopenharmony_ci}
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_cibool JSArrayBufferView::WasDetached() const {
1881cb0ef41Sopenharmony_ci  return JSArrayBuffer::cast(buffer()).was_detached();
1891cb0ef41Sopenharmony_ci}
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ciBIT_FIELD_ACCESSORS(JSArrayBufferView, bit_field, is_length_tracking,
1921cb0ef41Sopenharmony_ci                    JSArrayBufferView::IsLengthTrackingBit)
1931cb0ef41Sopenharmony_ciBIT_FIELD_ACCESSORS(JSArrayBufferView, bit_field, is_backed_by_rab,
1941cb0ef41Sopenharmony_ci                    JSArrayBufferView::IsBackedByRabBit)
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_cibool JSArrayBufferView::IsVariableLength() const {
1971cb0ef41Sopenharmony_ci  return is_length_tracking() || is_backed_by_rab();
1981cb0ef41Sopenharmony_ci}
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_cisize_t JSTypedArray::GetLengthOrOutOfBounds(bool& out_of_bounds) const {
2011cb0ef41Sopenharmony_ci  DCHECK(!out_of_bounds);
2021cb0ef41Sopenharmony_ci  if (WasDetached()) return 0;
2031cb0ef41Sopenharmony_ci  if (IsVariableLength()) {
2041cb0ef41Sopenharmony_ci    return GetVariableLengthOrOutOfBounds(out_of_bounds);
2051cb0ef41Sopenharmony_ci  }
2061cb0ef41Sopenharmony_ci  return LengthUnchecked();
2071cb0ef41Sopenharmony_ci}
2081cb0ef41Sopenharmony_ci
2091cb0ef41Sopenharmony_cisize_t JSTypedArray::GetLength() const {
2101cb0ef41Sopenharmony_ci  bool out_of_bounds = false;
2111cb0ef41Sopenharmony_ci  return GetLengthOrOutOfBounds(out_of_bounds);
2121cb0ef41Sopenharmony_ci}
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_cisize_t JSTypedArray::GetByteLength() const {
2151cb0ef41Sopenharmony_ci  return GetLength() * element_size();
2161cb0ef41Sopenharmony_ci}
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_cibool JSTypedArray::IsOutOfBounds() const {
2191cb0ef41Sopenharmony_ci  bool out_of_bounds = false;
2201cb0ef41Sopenharmony_ci  GetLengthOrOutOfBounds(out_of_bounds);
2211cb0ef41Sopenharmony_ci  return out_of_bounds;
2221cb0ef41Sopenharmony_ci}
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_cibool JSTypedArray::IsDetachedOrOutOfBounds() const {
2251cb0ef41Sopenharmony_ci  if (WasDetached()) {
2261cb0ef41Sopenharmony_ci    return true;
2271cb0ef41Sopenharmony_ci  }
2281cb0ef41Sopenharmony_ci  bool out_of_bounds = false;
2291cb0ef41Sopenharmony_ci  GetLengthOrOutOfBounds(out_of_bounds);
2301cb0ef41Sopenharmony_ci  return out_of_bounds;
2311cb0ef41Sopenharmony_ci}
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_cisize_t JSTypedArray::length() const {
2341cb0ef41Sopenharmony_ci  DCHECK(!is_length_tracking());
2351cb0ef41Sopenharmony_ci  DCHECK(!is_backed_by_rab());
2361cb0ef41Sopenharmony_ci  return ReadField<size_t>(kLengthOffset);
2371cb0ef41Sopenharmony_ci}
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_cisize_t JSTypedArray::LengthUnchecked() const {
2401cb0ef41Sopenharmony_ci  return ReadField<size_t>(kLengthOffset);
2411cb0ef41Sopenharmony_ci}
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_civoid JSTypedArray::set_length(size_t value) {
2441cb0ef41Sopenharmony_ci  WriteField<size_t>(kLengthOffset, value);
2451cb0ef41Sopenharmony_ci}
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ciDEF_GETTER(JSTypedArray, external_pointer, Address) {
2481cb0ef41Sopenharmony_ci  return ReadSandboxedPointerField(kExternalPointerOffset, cage_base);
2491cb0ef41Sopenharmony_ci}
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_civoid JSTypedArray::set_external_pointer(Isolate* isolate, Address value) {
2521cb0ef41Sopenharmony_ci  WriteSandboxedPointerField(kExternalPointerOffset, isolate, value);
2531cb0ef41Sopenharmony_ci}
2541cb0ef41Sopenharmony_ci
2551cb0ef41Sopenharmony_ciAddress JSTypedArray::ExternalPointerCompensationForOnHeapArray(
2561cb0ef41Sopenharmony_ci    PtrComprCageBase cage_base) {
2571cb0ef41Sopenharmony_ci#ifdef V8_COMPRESS_POINTERS
2581cb0ef41Sopenharmony_ci  return cage_base.address();
2591cb0ef41Sopenharmony_ci#else
2601cb0ef41Sopenharmony_ci  return 0;
2611cb0ef41Sopenharmony_ci#endif
2621cb0ef41Sopenharmony_ci}
2631cb0ef41Sopenharmony_ci
2641cb0ef41Sopenharmony_ciuint32_t JSTypedArray::GetExternalBackingStoreRefForDeserialization() const {
2651cb0ef41Sopenharmony_ci  DCHECK(!is_on_heap());
2661cb0ef41Sopenharmony_ci  return static_cast<uint32_t>(ReadField<Address>(kExternalPointerOffset));
2671cb0ef41Sopenharmony_ci}
2681cb0ef41Sopenharmony_ci
2691cb0ef41Sopenharmony_civoid JSTypedArray::SetExternalBackingStoreRefForSerialization(uint32_t ref) {
2701cb0ef41Sopenharmony_ci  DCHECK(!is_on_heap());
2711cb0ef41Sopenharmony_ci  WriteField<Address>(kExternalPointerOffset, static_cast<Address>(ref));
2721cb0ef41Sopenharmony_ci}
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_civoid JSTypedArray::RemoveExternalPointerCompensationForSerialization(
2751cb0ef41Sopenharmony_ci    Isolate* isolate) {
2761cb0ef41Sopenharmony_ci  DCHECK(is_on_heap());
2771cb0ef41Sopenharmony_ci  Address offset =
2781cb0ef41Sopenharmony_ci      external_pointer() - ExternalPointerCompensationForOnHeapArray(isolate);
2791cb0ef41Sopenharmony_ci  WriteField<Address>(kExternalPointerOffset, offset);
2801cb0ef41Sopenharmony_ci}
2811cb0ef41Sopenharmony_ci
2821cb0ef41Sopenharmony_civoid JSTypedArray::AddExternalPointerCompensationForDeserialization(
2831cb0ef41Sopenharmony_ci    Isolate* isolate) {
2841cb0ef41Sopenharmony_ci  DCHECK(is_on_heap());
2851cb0ef41Sopenharmony_ci  Address pointer = ReadField<Address>(kExternalPointerOffset) +
2861cb0ef41Sopenharmony_ci                    ExternalPointerCompensationForOnHeapArray(isolate);
2871cb0ef41Sopenharmony_ci  set_external_pointer(isolate, pointer);
2881cb0ef41Sopenharmony_ci}
2891cb0ef41Sopenharmony_ci
2901cb0ef41Sopenharmony_civoid* JSTypedArray::DataPtr() {
2911cb0ef41Sopenharmony_ci  // Zero-extend Tagged_t to Address according to current compression scheme
2921cb0ef41Sopenharmony_ci  // so that the addition with |external_pointer| (which already contains
2931cb0ef41Sopenharmony_ci  // compensated offset value) will decompress the tagged value.
2941cb0ef41Sopenharmony_ci  // See JSTypedArray::ExternalPointerCompensationForOnHeapArray() for details.
2951cb0ef41Sopenharmony_ci  STATIC_ASSERT(kOffHeapDataPtrEqualsExternalPointer);
2961cb0ef41Sopenharmony_ci  return reinterpret_cast<void*>(external_pointer() +
2971cb0ef41Sopenharmony_ci                                 static_cast<Tagged_t>(base_pointer().ptr()));
2981cb0ef41Sopenharmony_ci}
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_civoid JSTypedArray::SetOffHeapDataPtr(Isolate* isolate, void* base,
3011cb0ef41Sopenharmony_ci                                     Address offset) {
3021cb0ef41Sopenharmony_ci  Address address = reinterpret_cast<Address>(base) + offset;
3031cb0ef41Sopenharmony_ci  set_external_pointer(isolate, address);
3041cb0ef41Sopenharmony_ci  // This is the only spot in which the `base_pointer` field can be mutated
3051cb0ef41Sopenharmony_ci  // after object initialization. Note this can happen at most once, when
3061cb0ef41Sopenharmony_ci  // `JSTypedArray::GetBuffer` transitions from an on- to off-heap
3071cb0ef41Sopenharmony_ci  // representation.
3081cb0ef41Sopenharmony_ci  // To play well with Turbofan concurrency requirements, `base_pointer` is set
3091cb0ef41Sopenharmony_ci  // with a release store, after external_pointer has been set.
3101cb0ef41Sopenharmony_ci  set_base_pointer(Smi::zero(), kReleaseStore, SKIP_WRITE_BARRIER);
3111cb0ef41Sopenharmony_ci  DCHECK_EQ(address, reinterpret_cast<Address>(DataPtr()));
3121cb0ef41Sopenharmony_ci}
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_cibool JSTypedArray::is_on_heap() const {
3151cb0ef41Sopenharmony_ci  // Keep synced with `is_on_heap(AcquireLoadTag)`.
3161cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
3171cb0ef41Sopenharmony_ci  return base_pointer() != Smi::zero();
3181cb0ef41Sopenharmony_ci}
3191cb0ef41Sopenharmony_ci
3201cb0ef41Sopenharmony_cibool JSTypedArray::is_on_heap(AcquireLoadTag tag) const {
3211cb0ef41Sopenharmony_ci  // Keep synced with `is_on_heap()`.
3221cb0ef41Sopenharmony_ci  // Note: For Turbofan concurrency requirements, it's important that this
3231cb0ef41Sopenharmony_ci  // function reads only `base_pointer`.
3241cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
3251cb0ef41Sopenharmony_ci  return base_pointer(tag) != Smi::zero();
3261cb0ef41Sopenharmony_ci}
3271cb0ef41Sopenharmony_ci
3281cb0ef41Sopenharmony_ci// static
3291cb0ef41Sopenharmony_ciMaybeHandle<JSTypedArray> JSTypedArray::Validate(Isolate* isolate,
3301cb0ef41Sopenharmony_ci                                                 Handle<Object> receiver,
3311cb0ef41Sopenharmony_ci                                                 const char* method_name) {
3321cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(!receiver->IsJSTypedArray())) {
3331cb0ef41Sopenharmony_ci    const MessageTemplate message = MessageTemplate::kNotTypedArray;
3341cb0ef41Sopenharmony_ci    THROW_NEW_ERROR(isolate, NewTypeError(message), JSTypedArray);
3351cb0ef41Sopenharmony_ci  }
3361cb0ef41Sopenharmony_ci
3371cb0ef41Sopenharmony_ci  Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver);
3381cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(array->WasDetached())) {
3391cb0ef41Sopenharmony_ci    const MessageTemplate message = MessageTemplate::kDetachedOperation;
3401cb0ef41Sopenharmony_ci    Handle<String> operation =
3411cb0ef41Sopenharmony_ci        isolate->factory()->NewStringFromAsciiChecked(method_name);
3421cb0ef41Sopenharmony_ci    THROW_NEW_ERROR(isolate, NewTypeError(message, operation), JSTypedArray);
3431cb0ef41Sopenharmony_ci  }
3441cb0ef41Sopenharmony_ci
3451cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(array->IsVariableLength() && array->IsOutOfBounds())) {
3461cb0ef41Sopenharmony_ci    const MessageTemplate message = MessageTemplate::kDetachedOperation;
3471cb0ef41Sopenharmony_ci    Handle<String> operation =
3481cb0ef41Sopenharmony_ci        isolate->factory()->NewStringFromAsciiChecked(method_name);
3491cb0ef41Sopenharmony_ci    THROW_NEW_ERROR(isolate, NewTypeError(message, operation), JSTypedArray);
3501cb0ef41Sopenharmony_ci  }
3511cb0ef41Sopenharmony_ci
3521cb0ef41Sopenharmony_ci  // spec describes to return `buffer`, but it may disrupt current
3531cb0ef41Sopenharmony_ci  // implementations, and it's much useful to return array for now.
3541cb0ef41Sopenharmony_ci  return array;
3551cb0ef41Sopenharmony_ci}
3561cb0ef41Sopenharmony_ci
3571cb0ef41Sopenharmony_ciDEF_GETTER(JSDataView, data_pointer, void*) {
3581cb0ef41Sopenharmony_ci  Address value = ReadSandboxedPointerField(kDataPointerOffset, cage_base);
3591cb0ef41Sopenharmony_ci  return reinterpret_cast<void*>(value);
3601cb0ef41Sopenharmony_ci}
3611cb0ef41Sopenharmony_ci
3621cb0ef41Sopenharmony_civoid JSDataView::set_data_pointer(Isolate* isolate, void* ptr) {
3631cb0ef41Sopenharmony_ci  Address value = reinterpret_cast<Address>(ptr);
3641cb0ef41Sopenharmony_ci  WriteSandboxedPointerField(kDataPointerOffset, isolate, value);
3651cb0ef41Sopenharmony_ci}
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_ci}  // namespace internal
3681cb0ef41Sopenharmony_ci}  // namespace v8
3691cb0ef41Sopenharmony_ci
3701cb0ef41Sopenharmony_ci#include "src/objects/object-macros-undef.h"
3711cb0ef41Sopenharmony_ci
3721cb0ef41Sopenharmony_ci#endif  // V8_OBJECTS_JS_ARRAY_BUFFER_INL_H_
373