5#ifndef V8_OBJECTS_FIXED_ARRAY_INL_H_
6#define V8_OBJECTS_FIXED_ARRAY_INL_H_
37#include "torque-generated/src/objects/fixed-array-tq-inl.inc"
40int detail::ArrayHeaderBase<S, false>::capacity()
const {
41 return capacity_.
load().value();
45int detail::ArrayHeaderBase<S, false>::capacity(AcquireLoadTag tag)
const {
46 return capacity_.Acquire_Load().value();
50void detail::ArrayHeaderBase<S, false>::set_capacity(
int value) {
55void detail::ArrayHeaderBase<S, false>::set_capacity(
int value,
56 ReleaseStoreTag tag) {
61int detail::ArrayHeaderBase<S, true>::length()
const {
66int detail::ArrayHeaderBase<S, true>::length(AcquireLoadTag tag)
const {
67 return length_.Acquire_Load().value();
71void detail::ArrayHeaderBase<S, true>::set_length(
int value) {
76void detail::ArrayHeaderBase<S, true>::set_length(
int value,
77 ReleaseStoreTag tag) {
82int detail::ArrayHeaderBase<S, true>::capacity()
const {
87int detail::ArrayHeaderBase<S, true>::capacity(AcquireLoadTag tag)
const {
92void detail::ArrayHeaderBase<S, true>::set_capacity(
int value) {
97void detail::ArrayHeaderBase<S, true>::set_capacity(
int value,
98 ReleaseStoreTag tag) {
99 set_length(value, tag);
102template <
class D,
class S,
class P>
104 return static_cast<unsigned>(
index) <
static_cast<unsigned>(this->capacity());
107template <
class D,
class S,
class P>
109 return this->
map() ==
110 this->EarlyGetReadOnlyRoots().unchecked_fixed_cow_array_map();
113template <
class D,
class S,
class P>
116 DCHECK(IsInBounds(index));
118 return objects()[
index].Relaxed_Load();
121template <
class D,
class S,
class P>
125 return objects()[
index].Relaxed_Load();
128template <
class D,
class S,
class P>
132 return objects()[
index].Acquire_Load();
135template <
class D,
class S,
class P>
138 DCHECK(IsInBounds(index));
139 return objects()[
index].SeqCst_Load();
142template <
class D,
class S,
class P>
146 DCHECK(IsInBounds(index));
148 objects()[
index].Relaxed_Store(
this, value, mode);
151template <
class D,
class S,
class P>
152template <
typename,
typename>
157template <
class D,
class S,
class P>
161 DCHECK(IsInBounds(index));
162 objects()[
index].Relaxed_Store(
this, value, mode);
165template <
class D,
class S,
class P>
166template <
typename,
typename>
172template <
class D,
class S,
class P>
176 DCHECK(IsInBounds(index));
177 objects()[
index].Release_Store(
this, value, mode);
180template <
class D,
class S,
class P>
181template <
typename,
typename>
187template <
class D,
class S,
class P>
191 DCHECK(IsInBounds(index));
192 objects()[
index].SeqCst_Store(
this, value, mode);
195template <
class D,
class S,
class P>
196template <
typename,
typename>
202template <
class D,
class S,
class P>
207 DCHECK(IsInBounds(index));
208 return objects()[
index].SeqCst_Swap(
this, value, mode);
211template <
class D,
class S,
class P>
218 DCHECK(IsInBounds(index));
219 return objects()[
index].SeqCst_CompareAndSwap(
this, expected, value, mode);
222template <
class D,
class S,
class P>
225 int src_index,
int len,
227 if (len == 0)
return;
230 DCHECK(dst->IsInBounds(dst_index));
231 DCHECK_LE(dst_index + len, dst->length());
232 DCHECK(src->IsInBounds(src_index));
233 DCHECK_LE(src_index + len, src->length());
236 SlotType dst_slot(&dst->objects()[dst_index]);
237 SlotType src_slot(&src->objects()[src_index]);
238 isolate->heap()->MoveRange(dst, dst_slot, src_slot, len, mode);
241template <
class D,
class S,
class P>
244 int src_index,
int len,
246 if (len == 0)
return;
249 DCHECK(dst->IsInBounds(dst_index));
250 DCHECK_LE(dst_index + len, dst->capacity());
251 DCHECK(src->IsInBounds(src_index));
252 DCHECK_LE(src_index + len, src->capacity());
255 SlotType dst_slot(&dst->objects()[dst_index]);
256 SlotType src_slot(&src->objects()[src_index]);
257 isolate->heap()->CopyRange(dst, dst_slot, src_slot, len, mode);
260template <
class D,
class S,
class P>
262 int old_capacity = this->capacity();
264 CHECK_LE(new_capacity, old_capacity);
265 if (new_capacity == old_capacity)
return;
266 isolate->heap()->RightTrimArray(
Cast<D>(
this), new_capacity, old_capacity);
272template <
class D,
class S,
class P>
277template <
class D,
class S,
class P>
280 return RawFieldOfElementAt(0);
283template <
class D,
class S,
class P>
290template <
class IsolateT>
295 FATAL(
"Fatal JavaScript invalid size error %d (see crbug.com/1201626)",
298 return isolate->factory()->empty_fixed_array();
301 std::optional<DisallowGarbageCollection> no_gc;
305 MemsetTagged((*result)->RawFieldOfFirstElement(), roots.undefined_value(),
311template <
class IsolateT>
320 FATAL(
"Fatal JavaScript invalid size error %d (see crbug.com/1201626)",
328 std::optional<DisallowGarbageCollection> no_gc;
336template <
class IsolateT>
341 FATAL(
"Fatal JavaScript invalid size error %d (see crbug.com/1201626)",
345 std::optional<DisallowGarbageCollection> no_gc;
353template <
class D,
class S,
class P>
354template <
class IsolateT>
356 IsolateT* isolate,
int capacity,
357 std::optional<DisallowGarbageCollection>* no_gc_out,
363 DCHECK(!no_gc_out->has_value());
366 isolate->factory()->AllocateRawArray(SizeFor(capacity), allocation));
374 xs->set_capacity(capacity);
376 return handle(xs, isolate);
380template <
class D,
class S,
class P>
385 int capacity = old_capacity;
387 capacity = capacity + (capacity >> 1) + 16;
388 }
while (capacity <= index);
397 return IsTheHole(get(index), isolate);
410 for (
int i = from;
i <
to;
i++) {
433 int elements_to_copy = std::min(new_capacity, xs->capacity());
440template <
class D,
class S,
class P>
442 return static_cast<unsigned>(
index) <
static_cast<unsigned>(this->
length());
445template <
class D,
class S,
class P>
447 DCHECK(IsInBounds(index));
448 return values()[
index];
451template <
class D,
class S,
class P>
453 DCHECK(IsInBounds(index));
460template <
class D,
class S,
class P>
465template <
class D,
class S,
class P>
470template <
class D,
class S,
class P>
475template <
class D,
class S,
class P>
477 return &values()[this->
length()];
480template <
class D,
class S,
class P>
482 return &values()[this->
length()];
485template <
class D,
class S,
class P>
487 int data_size = SizeFor(this->
length()) -
sizeof(
Header);
493template <
class D,
class S,
class P>
501template <
class IsolateT>
505 FATAL(
"Fatal JavaScript invalid size error %d (see crbug.com/1201626)",
508 return isolate->factory()->empty_fixed_array();
511 std::optional<DisallowGarbageCollection> no_gc;
516template <
class D,
class S,
class P>
517template <
class IsolateT>
519 IsolateT* isolate,
int length,
520 std::optional<DisallowGarbageCollection>* no_gc_out,
526 DCHECK(!no_gc_out->has_value());
529 isolate->factory()->AllocateRawArray(SizeFor(length), allocation));
537 xs->set_length(length);
539 return handle(xs, isolate);
544 return values()[
index].value();
549 return values()[
index].value_as_bits();
554 if (array->is_the_hole(index)) {
555 return isolate->factory()->the_hole_value();
556#ifdef V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE
557 }
else if (array->is_undefined(index)) {
558 return isolate->factory()->undefined_value();
561 return isolate->factory()->NewNumber(array->get_scalar(index));
566 if (std::isnan(value)) {
567#ifdef V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE
568 DCHECK(!IsUndefinedNan(value));
570 value = std::numeric_limits<double>::quiet_NaN();
572 values()[
index].set_value(value);
576#ifdef V8_ENABLE_EXPERIMENTAL_UNDEFINED_DOUBLE
577void FixedDoubleArray::set_undefined(
int index) {
578 values()[
index].set_value(UndefinedNan());
580 DCHECK(is_undefined(index));
583bool FixedDoubleArray::is_undefined(
int index) {
606 int src_index,
int len,
613 for (
int i = from;
i <
to;
i++) {
619template <
class IsolateT>
626 return isolate->factory()->empty_weak_fixed_array();
629 std::optional<DisallowGarbageCollection> no_gc;
634 initial_value.
is_null() ? roots.undefined_value()
640template <
class IsolateT>
645 FATAL(
"Fatal JavaScript invalid size error %d (see crbug.com/1201626)",
649 std::optional<DisallowGarbageCollection> no_gc;
656template <
class IsolateT>
661 FATAL(
"Fatal JavaScript invalid size error %d (see crbug.com/1201626)",
664 std::optional<DisallowGarbageCollection> no_gc;
673 return Get(cage_base, index);
679 DCHECK_LT(
static_cast<unsigned>(index),
static_cast<unsigned>(capacity()));
693 return RawMaybeWeakField(kObjectsOffset);
699 if (len == 0)
return;
701 DCHECK_LE(src_index + len, src->capacity());
706 isolate->heap()->CopyRange(*
this, dst_slot, src_slot, len, mode);
721int ArrayList ::length()
const {
return length_.load().value(); }
722void ArrayList ::set_length(
int value) {
727template <
class IsolateT>
730 if (capacity == 0)
return isolate->factory()->empty_array_list();
735 std::optional<DisallowGarbageCollection> no_gc;
746template <
class IsolateT>
749 if (
V8_UNLIKELY(
static_cast<unsigned>(length) > kMaxLength)) {
750 FATAL(
"Fatal JavaScript invalid size error %d", length);
752 return isolate->factory()->empty_byte_array();
755 std::optional<DisallowGarbageCollection> no_gc;
760 memset(&
result->values()[length], 0, padding_size);
780template <
class IsolateT>
785 if (
V8_UNLIKELY(
static_cast<unsigned>(length) > kMaxLength)) {
786 FATAL(
"Fatal JavaScript invalid size error %d", length);
789 std::optional<DisallowGarbageCollection> no_gc;
791 Allocate(isolate, length, &no_gc, allocation_type));
794 memset(&
result->values()[length], 0, padding_size);
813template <
typename Base>
814template <
typename... MoreArgs>
817 Isolate* isolate,
int length, MoreArgs&&... more_args) {
819 Underlying::New(isolate, length, std::forward<MoreArgs>(more_args)...));
822template <
typename T,
typename Base>
823template <
typename... MoreArgs>
826 Isolate* isolate,
int length, MoreArgs&&... more_args) {
830 Base::New(isolate, byte_length, std::forward<MoreArgs>(more_args)...));
833template <
typename T,
typename Base>
837 return reinterpret_cast<Address>(&this->values()[index *
sizeof(
T)]);
840template <
typename T,
typename Base>
842 static_assert(std::is_integral<T>::value);
846template <
typename T,
typename Base>
848 static_assert(std::is_integral<T>::value);
852template <
typename T,
typename Base>
854 DCHECK_EQ(Base::length() %
sizeof(T), 0);
855 return Base::length() /
sizeof(
T);
858template <
typename Base>
865template <
typename Base>
873template <
class T,
class Super>
875 return Super::length() /
sizeof(
T);
885 isolate->factory()->NewByteArray(byte_length, allocation));
895 isolate->factory()->NewByteArray(byte_length, allocation));
905 isolate->factory()->NewTrustedByteArray(byte_length));
915 isolate->factory()->NewTrustedByteArray(byte_length));
#define DCHECK_TAG_ALIGNED(address)
static DirectHandle< ArrayList > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kYoung)
static Handle< ByteArray > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kYoung)
uint32_t get_int(int offset) const
void set_int(int offset, uint32_t value)
void set_sandboxed_pointer(int index, Address value)
static DirectHandle< FixedAddressArrayBase > New(Isolate *isolate, int length, MoreArgs &&... more_args)
Address get_sandboxed_pointer(int index) const
static constexpr int kMaxLength
static Handle< FixedArray > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kYoung)
void CopyElements(Isolate *isolate, int dst_index, Tagged< FixedArray > src, int src_index, int len, WriteBarrierMode mode)
void FillWithHoles(int from, int to)
static Handle< FixedArray > Resize(Isolate *isolate, DirectHandle< FixedArray > xs, int new_capacity, AllocationType allocation=AllocationType::kYoung, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
void set_the_hole(Isolate *isolate, int index)
void MoveElements(Isolate *isolate, int dst_index, int src_index, int len, WriteBarrierMode mode)
void set_the_hole(Isolate *isolate, int index)
bool is_the_hole(Isolate *isolate, int index)
uint64_t get_representation(int index)
void set(int index, double value)
static Handle< Object > get(Tagged< FixedDoubleArray > array, int index, Isolate *isolate)
void MoveElements(Isolate *isolate, int dst_index, int src_index, int len, WriteBarrierMode)
double get_scalar(int index)
static Handle< FixedArrayBase > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kYoung)
void FillWithHoles(int from, int to)
void set(int index, T value)
Address get_element_address(int index) const
static Handle< FixedIntegerArrayBase< T, Base > > New(Isolate *isolate, int length, MoreArgs &&... more_args)
V8_INLINE DirectHandle< T > ToHandleChecked() const
V8_INLINE bool is_null() const
static Handle< PodArray< T > > New(Isolate *isolate, int length, AllocationType allocation=AllocationType::kYoung)
int AllocatedSize() const
static constexpr int kMaxLength
static constexpr int kElementSize
static Tagged< Derived > FromAddressOfFirstElement(Address address)
void set(int index, ElementMemberT value)
ElementMemberT get(int index) const
std::conditional_t< std::is_same_v< ElementT, double >, UnalignedDoubleMember, ElementT > ElementMemberT
static Handle< FixedDoubleArray > Allocate(IsolateT *isolate, int length, std::optional< DisallowGarbageCollection > *no_gc_out, AllocationType allocation=AllocationType::kYoung)
bool IsInBounds(int index) const
static constexpr int kMaxLength
static Handle< ProtectedFixedArray > New(IsolateT *isolate, int capacity)
static Handle< ProtectedWeakFixedArray > New(IsolateT *isolate, int capacity)
static V8_EXPORT_PRIVATE bool Contains(Address address)
static constexpr Tagged< Smi > FromInt(int value)
static constexpr Tagged< Smi > zero()
static Handle< FixedArray > Allocate(IsolateT *isolate, int capacity, std::optional< DisallowGarbageCollection > *no_gc_out, AllocationType allocation=AllocationType::kYoung)
void RightTrim(Isolate *isolate, int new_capacity)
Tagged< ElementT > compare_and_swap(int index, Tagged< ElementT > expected, Tagged< ElementT > value, SeqCstAccessTag, WriteBarrierMode mode=kDefaultMode)
SlotType RawFieldOfElementAt(int index) const
static void CopyElements(Isolate *isolate, Tagged< Derived > dst, int dst_index, Tagged< Derived > src, int src_index, int len, WriteBarrierMode mode=kDefaultMode)
Tagged< ElementT > swap(int index, Tagged< ElementT > value, SeqCstAccessTag, WriteBarrierMode mode=kDefaultMode)
int AllocatedSize() const
std::conditional_t< kElementsAreMaybeObject, MaybeObjectSlot, ObjectSlot > SlotType
void set(int index, Tagged< ElementT > value, WriteBarrierMode mode=kDefaultMode)
bool IsInBounds(int index) const
static void MoveElements(Isolate *isolate, Tagged< Derived > dst, int dst_index, Tagged< Derived > src, int src_index, int len, WriteBarrierMode mode=kDefaultMode)
static constexpr int kMaxCapacity
SlotType RawFieldOfFirstElement() const
Tagged< ElementT > get(int index) const
static constexpr int NewCapacityForIndex(int index, int old_capacity)
constexpr bool IsCleared() const
constexpr bool IsWeakOrCleared() const
Tagged< HeapObject > GetHeapObjectAssumeWeak() const
void set_int(int offset, uint32_t value)
uint32_t get_int(int offset) const
static Handle< TrustedByteArray > New(IsolateT *isolate, int capacity, AllocationType allocation_type=AllocationType::kTrusted)
static Handle< TrustedFixedArray > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kTrusted)
static constexpr int kMaxLength
static DirectHandle< TrustedPodArray< T > > New(Isolate *isolate, int length)
static Handle< TrustedWeakFixedArray > New(IsolateT *isolate, int capacity)
Tagged< HeapObject > Next()
Tagged< WeakArrayList > array_
static int OffsetOfElementAt(int index)
void CopyElements(Isolate *isolate, int dst_index, Tagged< WeakArrayList > src, int src_index, int len, WriteBarrierMode mode)
Tagged< MaybeObject > get(int index) const
void Set(int index, Tagged< MaybeObject > value, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
static constexpr int kMaxCapacity
MaybeObjectSlot data_start()
Tagged< MaybeObject > Get(int index) const
int AllocatedSize() const
static Handle< WeakFixedArray > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kYoung, MaybeDirectHandle< Object > initial_value={})
#define OBJECT_POINTER_ALIGN(value)
ZoneVector< RpoNumber > & result
bool SignedMulOverflow32(int32_t lhs, int32_t rhs, int32_t *val)
static V ReadUnalignedValue(Address p)
static void WriteUnalignedValue(Address p, V value)
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
ReadOnlyRoots GetReadOnlyRoots()
V8_INLINE Address ReadSandboxedPointerField(Address field_address, PtrComprCageBase cage_base)
constexpr uint64_t kHoleNanInt64
kInterpreterTrampolineOffset Tagged< HeapObject >
void MemsetTagged(Tagged_t *start, Tagged< MaybeObject > value, size_t counter)
Handle< To > UncheckedCast(Handle< From > value)
V8_INLINE PtrComprCageBase GetPtrComprCageBase()
V8_EXPORT_PRIVATE void MemMove(void *dest, const void *src, size_t size)
V8_INLINE void WriteSandboxedPointerField(Address field_address, PtrComprCageBase cage_base, Address pointer)
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
static constexpr RelaxedLoadTag kRelaxedLoad
static constexpr RelaxedStoreTag kRelaxedStore
static constexpr AcquireLoadTag kAcquireLoad
#define TQ_OBJECT_CONSTRUCTORS_IMPL(Type)
#define NEVER_READ_ONLY_SPACE_IMPL(Type)
#define DCHECK_LE(v1, v2)
#define CHECK_GT(lhs, rhs)
#define CHECK_LE(lhs, rhs)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
#define V8_UNLIKELY(condition)