Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_OBJECTS_FIXED_ARRAY_H_
6 : #define V8_OBJECTS_FIXED_ARRAY_H_
7 :
8 : #include "src/maybe-handles.h"
9 : #include "src/objects/instance-type.h"
10 : #include "src/objects/smi.h"
11 : #include "torque-generated/class-definitions-from-dsl.h"
12 :
13 : // Has to be the last include (doesn't have include guards):
14 : #include "src/objects/object-macros.h"
15 :
16 : namespace v8 {
17 : namespace internal {
18 : using WeakArrayBodyDescriptor =
19 : FlexibleWeakBodyDescriptor<HeapObject::kHeaderSize>;
20 :
21 : #define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V) \
22 : V(BYTECODE_ARRAY_CONSTANT_POOL_SUB_TYPE) \
23 : V(BYTECODE_ARRAY_HANDLER_TABLE_SUB_TYPE) \
24 : V(CODE_STUBS_TABLE_SUB_TYPE) \
25 : V(COMPILATION_CACHE_TABLE_SUB_TYPE) \
26 : V(CONTEXT_SUB_TYPE) \
27 : V(COPY_ON_WRITE_SUB_TYPE) \
28 : V(DEOPTIMIZATION_DATA_SUB_TYPE) \
29 : V(DESCRIPTOR_ARRAY_SUB_TYPE) \
30 : V(EMBEDDED_OBJECT_SUB_TYPE) \
31 : V(ENUM_CACHE_SUB_TYPE) \
32 : V(ENUM_INDICES_CACHE_SUB_TYPE) \
33 : V(DEPENDENT_CODE_SUB_TYPE) \
34 : V(DICTIONARY_ELEMENTS_SUB_TYPE) \
35 : V(DICTIONARY_PROPERTIES_SUB_TYPE) \
36 : V(EMPTY_PROPERTIES_DICTIONARY_SUB_TYPE) \
37 : V(PACKED_ELEMENTS_SUB_TYPE) \
38 : V(FAST_PROPERTIES_SUB_TYPE) \
39 : V(FAST_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE) \
40 : V(HANDLER_TABLE_SUB_TYPE) \
41 : V(JS_COLLECTION_SUB_TYPE) \
42 : V(JS_WEAK_COLLECTION_SUB_TYPE) \
43 : V(NOSCRIPT_SHARED_FUNCTION_INFOS_SUB_TYPE) \
44 : V(NUMBER_STRING_CACHE_SUB_TYPE) \
45 : V(OBJECT_TO_CODE_SUB_TYPE) \
46 : V(OPTIMIZED_CODE_LITERALS_SUB_TYPE) \
47 : V(OPTIMIZED_CODE_MAP_SUB_TYPE) \
48 : V(PROTOTYPE_USERS_SUB_TYPE) \
49 : V(REGEXP_MULTIPLE_CACHE_SUB_TYPE) \
50 : V(RETAINED_MAPS_SUB_TYPE) \
51 : V(SCOPE_INFO_SUB_TYPE) \
52 : V(SCRIPT_LIST_SUB_TYPE) \
53 : V(SERIALIZED_OBJECTS_SUB_TYPE) \
54 : V(SHARED_FUNCTION_INFOS_SUB_TYPE) \
55 : V(SINGLE_CHARACTER_STRING_CACHE_SUB_TYPE) \
56 : V(SLOW_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE) \
57 : V(STRING_SPLIT_CACHE_SUB_TYPE) \
58 : V(STRING_TABLE_SUB_TYPE) \
59 : V(TEMPLATE_INFO_SUB_TYPE) \
60 : V(FEEDBACK_METADATA_SUB_TYPE) \
61 : V(WEAK_NEW_SPACE_OBJECT_TO_CODE_SUB_TYPE)
62 :
63 : enum FixedArraySubInstanceType {
64 : #define DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE(name) name,
65 : FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE)
66 : #undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
67 : LAST_FIXED_ARRAY_SUB_TYPE = WEAK_NEW_SPACE_OBJECT_TO_CODE_SUB_TYPE
68 : };
69 :
70 : // Common superclass for FixedArrays that allow implementations to share
71 : // common accessors and some code paths.
72 : class FixedArrayBase : public HeapObject {
73 : public:
74 : // [length]: length of the array.
75 : inline int length() const;
76 : inline void set_length(int value);
77 :
78 : // Get and set the length using acquire loads and release stores.
79 : inline int synchronized_length() const;
80 : inline void synchronized_set_length(int value);
81 :
82 : inline Object unchecked_synchronized_length() const;
83 :
84 : DECL_CAST(FixedArrayBase)
85 :
86 : static int GetMaxLengthForNewSpaceAllocation(ElementsKind kind);
87 :
88 : V8_EXPORT_PRIVATE bool IsCowArray() const;
89 :
90 : // Maximal allowed size, in bytes, of a single FixedArrayBase.
91 : // Prevents overflowing size computations, as well as extreme memory
92 : // consumption.
93 : #ifdef V8_HOST_ARCH_32_BIT
94 : static const int kMaxSize = 512 * MB;
95 : #else
96 : static const int kMaxSize = 1024 * MB;
97 : #endif // V8_HOST_ARCH_32_BIT
98 :
99 : // Layout description.
100 : DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
101 : TORQUE_GENERATED_FIXED_ARRAY_BASE_FIELDS)
102 :
103 : static const int kHeaderSize = kSize;
104 :
105 : protected:
106 : // Special-purpose constructor for subclasses that have fast paths where
107 : // their ptr() is a Smi.
108 : inline FixedArrayBase(Address ptr, AllowInlineSmiStorage allow_smi);
109 :
110 : OBJECT_CONSTRUCTORS(FixedArrayBase, HeapObject);
111 : };
112 :
113 : // FixedArray describes fixed-sized arrays with element type Object.
114 : class FixedArray : public FixedArrayBase {
115 : public:
116 : // Setter and getter for elements.
117 : inline Object get(int index) const;
118 : static inline Handle<Object> get(FixedArray array, int index,
119 : Isolate* isolate);
120 : template <class T>
121 : MaybeHandle<T> GetValue(Isolate* isolate, int index) const;
122 :
123 : template <class T>
124 : Handle<T> GetValueChecked(Isolate* isolate, int index) const;
125 :
126 : // Return a grown copy if the index is bigger than the array's length.
127 : V8_EXPORT_PRIVATE static Handle<FixedArray> SetAndGrow(
128 : Isolate* isolate, Handle<FixedArray> array, int index,
129 : Handle<Object> value, AllocationType allocation = AllocationType::kYoung);
130 :
131 : // Setter that uses write barrier.
132 : inline void set(int index, Object value);
133 : inline bool is_the_hole(Isolate* isolate, int index);
134 :
135 : // Setter that doesn't need write barrier.
136 : inline void set(int index, Smi value);
137 : // Setter with explicit barrier mode.
138 : inline void set(int index, Object value, WriteBarrierMode mode);
139 :
140 : // Setters for frequently used oddballs located in old space.
141 : inline void set_undefined(int index);
142 : inline void set_undefined(Isolate* isolate, int index);
143 : inline void set_null(int index);
144 : inline void set_null(Isolate* isolate, int index);
145 : inline void set_the_hole(int index);
146 : inline void set_the_hole(Isolate* isolate, int index);
147 :
148 : inline ObjectSlot GetFirstElementAddress();
149 : inline bool ContainsOnlySmisOrHoles();
150 : // Returns true iff the elements are Numbers and sorted ascending.
151 : bool ContainsSortedNumbers();
152 :
153 : // Gives access to raw memory which stores the array's data.
154 : inline ObjectSlot data_start();
155 :
156 : inline void MoveElements(Heap* heap, int dst_index, int src_index, int len,
157 : WriteBarrierMode mode);
158 :
159 : inline void CopyElements(Heap* heap, int dst_index, FixedArray src,
160 : int src_index, int len, WriteBarrierMode mode);
161 :
162 : inline void FillWithHoles(int from, int to);
163 :
164 : // Shrink the array and insert filler objects. {new_length} must be > 0.
165 : V8_EXPORT_PRIVATE void Shrink(Isolate* isolate, int new_length);
166 : // If {new_length} is 0, return the canonical empty FixedArray. Otherwise
167 : // like above.
168 : static Handle<FixedArray> ShrinkOrEmpty(Isolate* isolate,
169 : Handle<FixedArray> array,
170 : int new_length);
171 :
172 : // Copy a sub array from the receiver to dest.
173 : V8_EXPORT_PRIVATE void CopyTo(int pos, FixedArray dest, int dest_pos,
174 : int len) const;
175 :
176 : // Garbage collection support.
177 : static constexpr int SizeFor(int length) {
178 144905777 : return kHeaderSize + length * kTaggedSize;
179 : }
180 :
181 : // Code Generation support.
182 : static constexpr int OffsetOfElementAt(int index) { return SizeFor(index); }
183 :
184 : // Garbage collection support.
185 : inline ObjectSlot RawFieldOfElementAt(int index);
186 :
187 : DECL_CAST(FixedArray)
188 : // Maximally allowed length of a FixedArray.
189 : static const int kMaxLength = (kMaxSize - kHeaderSize) / kTaggedSize;
190 : static_assert(Internals::IsValidSmi(kMaxLength),
191 : "FixedArray maxLength not a Smi");
192 :
193 : // Maximally allowed length for regular (non large object space) object.
194 : STATIC_ASSERT(kMaxRegularHeapObjectSize < kMaxSize);
195 : static const int kMaxRegularLength =
196 : (kMaxRegularHeapObjectSize - kHeaderSize) / kTaggedSize;
197 :
198 : // Dispatched behavior.
199 : DECL_PRINTER(FixedArray)
200 : DECL_VERIFIER(FixedArray)
201 :
202 : using BodyDescriptor = FlexibleBodyDescriptor<kHeaderSize>;
203 :
204 : protected:
205 : // Set operation on FixedArray without using write barriers. Can
206 : // only be used for storing old space objects or smis.
207 : static inline void NoWriteBarrierSet(FixedArray array, int index,
208 : Object value);
209 :
210 : private:
211 : STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
212 :
213 : inline void set_undefined(ReadOnlyRoots ro_roots, int index);
214 : inline void set_null(ReadOnlyRoots ro_roots, int index);
215 : inline void set_the_hole(ReadOnlyRoots ro_roots, int index);
216 :
217 : OBJECT_CONSTRUCTORS(FixedArray, FixedArrayBase);
218 : };
219 :
220 : // FixedArray alias added only because of IsFixedArrayExact() predicate, which
221 : // checks for the exact instance type FIXED_ARRAY_TYPE instead of a range
222 : // check: [FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE].
223 : class FixedArrayExact final : public FixedArray {};
224 :
225 : // FixedDoubleArray describes fixed-sized arrays with element type double.
226 : class FixedDoubleArray : public FixedArrayBase {
227 : public:
228 : // Setter and getter for elements.
229 : inline double get_scalar(int index);
230 : inline uint64_t get_representation(int index);
231 : static inline Handle<Object> get(FixedDoubleArray array, int index,
232 : Isolate* isolate);
233 : inline void set(int index, double value);
234 : inline void set_the_hole(Isolate* isolate, int index);
235 : inline void set_the_hole(int index);
236 :
237 : // Checking for the hole.
238 : inline bool is_the_hole(Isolate* isolate, int index);
239 : inline bool is_the_hole(int index);
240 :
241 : // Garbage collection support.
242 : inline static int SizeFor(int length) {
243 1299911 : return kHeaderSize + length * kDoubleSize;
244 : }
245 :
246 : inline void MoveElements(Heap* heap, int dst_index, int src_index, int len,
247 : WriteBarrierMode mode);
248 :
249 : inline void FillWithHoles(int from, int to);
250 :
251 : // Code Generation support.
252 : static int OffsetOfElementAt(int index) { return SizeFor(index); }
253 :
254 : DECL_CAST(FixedDoubleArray)
255 :
256 : // Maximally allowed length of a FixedArray.
257 : static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
258 : static_assert(Internals::IsValidSmi(kMaxLength),
259 : "FixedDoubleArray maxLength not a Smi");
260 :
261 : // Dispatched behavior.
262 : DECL_PRINTER(FixedDoubleArray)
263 : DECL_VERIFIER(FixedDoubleArray)
264 :
265 : class BodyDescriptor;
266 :
267 : OBJECT_CONSTRUCTORS(FixedDoubleArray, FixedArrayBase);
268 : };
269 :
270 : // WeakFixedArray describes fixed-sized arrays with element type
271 : // MaybeObject.
272 : class WeakFixedArray : public HeapObject {
273 : public:
274 : DECL_CAST(WeakFixedArray)
275 :
276 : inline MaybeObject Get(int index) const;
277 :
278 : // Setter that uses write barrier.
279 : inline void Set(int index, MaybeObject value);
280 :
281 : // Setter with explicit barrier mode.
282 : inline void Set(int index, MaybeObject value, WriteBarrierMode mode);
283 :
284 : static constexpr int SizeFor(int length) {
285 13726525 : return kHeaderSize + length * kTaggedSize;
286 : }
287 :
288 : DECL_INT_ACCESSORS(length)
289 :
290 : // Get and set the length using acquire loads and release stores.
291 : inline int synchronized_length() const;
292 : inline void synchronized_set_length(int value);
293 :
294 : // Gives access to raw memory which stores the array's data.
295 : inline MaybeObjectSlot data_start();
296 :
297 : inline MaybeObjectSlot RawFieldOfElementAt(int index);
298 :
299 : DECL_PRINTER(WeakFixedArray)
300 : DECL_VERIFIER(WeakFixedArray)
301 :
302 : using BodyDescriptor = WeakArrayBodyDescriptor;
303 :
304 : // Layout description.
305 : #define WEAK_FIXED_ARRAY_FIELDS(V) \
306 : V(kLengthOffset, kTaggedSize) \
307 : /* Header size. */ \
308 : V(kHeaderSize, 0)
309 :
310 : DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
311 : WEAK_FIXED_ARRAY_FIELDS)
312 : #undef WEAK_FIXED_ARRAY_FIELDS
313 :
314 : static const int kMaxLength =
315 : (FixedArray::kMaxSize - kHeaderSize) / kTaggedSize;
316 : static_assert(Internals::IsValidSmi(kMaxLength),
317 : "WeakFixedArray maxLength not a Smi");
318 :
319 : protected:
320 : static int OffsetOfElementAt(int index) {
321 241370484 : return kHeaderSize + index * kTaggedSize;
322 : }
323 :
324 : private:
325 : friend class Heap;
326 :
327 : static const int kFirstIndex = 1;
328 :
329 : OBJECT_CONSTRUCTORS(WeakFixedArray, HeapObject);
330 : };
331 :
332 : // WeakArrayList is like a WeakFixedArray with static convenience methods for
333 : // adding more elements. length() returns the number of elements in the list and
334 : // capacity() returns the allocated size. The number of elements is stored at
335 : // kLengthOffset and is updated with every insertion. The array grows
336 : // dynamically with O(1) amortized insertion.
337 : class WeakArrayList : public HeapObject {
338 : public:
339 : NEVER_READ_ONLY_SPACE
340 : DECL_CAST(WeakArrayList)
341 : DECL_VERIFIER(WeakArrayList)
342 : DECL_PRINTER(WeakArrayList)
343 :
344 : V8_EXPORT_PRIVATE static Handle<WeakArrayList> AddToEnd(
345 : Isolate* isolate, Handle<WeakArrayList> array,
346 : const MaybeObjectHandle& value);
347 :
348 : inline MaybeObject Get(int index) const;
349 :
350 : // Set the element at index to obj. The underlying array must be large enough.
351 : // If you need to grow the WeakArrayList, use the static AddToEnd() method
352 : // instead.
353 : inline void Set(int index, MaybeObject value,
354 : WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
355 :
356 : static constexpr int SizeForCapacity(int capacity) {
357 5413953 : return kHeaderSize + capacity * kTaggedSize;
358 : }
359 :
360 : // Gives access to raw memory which stores the array's data.
361 : inline MaybeObjectSlot data_start();
362 :
363 : V8_EXPORT_PRIVATE bool IsFull();
364 :
365 : DECL_INT_ACCESSORS(capacity)
366 : DECL_INT_ACCESSORS(length)
367 :
368 : // Get and set the capacity using acquire loads and release stores.
369 : inline int synchronized_capacity() const;
370 : inline void synchronized_set_capacity(int value);
371 :
372 :
373 : // Layout description.
374 : #define WEAK_ARRAY_LIST_FIELDS(V) \
375 : V(kCapacityOffset, kTaggedSize) \
376 : V(kLengthOffset, kTaggedSize) \
377 : /* Header size. */ \
378 : V(kHeaderSize, 0)
379 :
380 : DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, WEAK_ARRAY_LIST_FIELDS)
381 : #undef WEAK_ARRAY_LIST_FIELDS
382 :
383 : using BodyDescriptor = WeakArrayBodyDescriptor;
384 :
385 : static const int kMaxCapacity =
386 : (FixedArray::kMaxSize - kHeaderSize) / kTaggedSize;
387 :
388 : static Handle<WeakArrayList> EnsureSpace(
389 : Isolate* isolate, Handle<WeakArrayList> array, int length,
390 : AllocationType allocation = AllocationType::kYoung);
391 :
392 : // Returns the number of non-cleaned weak references in the array.
393 : int CountLiveWeakReferences() const;
394 :
395 : // Returns whether an entry was found and removed. Will move the elements
396 : // around in the array - this method can only be used in cases where the user
397 : // doesn't care about the indices! Users should make sure there are no
398 : // duplicates.
399 : V8_EXPORT_PRIVATE bool RemoveOne(const MaybeObjectHandle& value);
400 :
401 : class Iterator;
402 :
403 : private:
404 : static int OffsetOfElementAt(int index) {
405 67135343 : return kHeaderSize + index * kTaggedSize;
406 : }
407 :
408 : OBJECT_CONSTRUCTORS(WeakArrayList, HeapObject);
409 : };
410 :
411 : class WeakArrayList::Iterator {
412 : public:
413 135736 : explicit Iterator(WeakArrayList array) : index_(0), array_(array) {}
414 :
415 : inline HeapObject Next();
416 :
417 : private:
418 : int index_;
419 : WeakArrayList array_;
420 : #ifdef DEBUG
421 : DisallowHeapAllocation no_gc_;
422 : #endif // DEBUG
423 : DISALLOW_COPY_AND_ASSIGN(Iterator);
424 : };
425 :
426 : // Generic array grows dynamically with O(1) amortized insertion.
427 : //
428 : // ArrayList is a FixedArray with static convenience methods for adding more
429 : // elements. The Length() method returns the number of elements in the list, not
430 : // the allocated size. The number of elements is stored at kLengthIndex and is
431 : // updated with every insertion. The elements of the ArrayList are stored in the
432 : // underlying FixedArray starting at kFirstIndex.
433 : class ArrayList : public FixedArray {
434 : public:
435 : V8_EXPORT_PRIVATE static Handle<ArrayList> Add(Isolate* isolate,
436 : Handle<ArrayList> array,
437 : Handle<Object> obj);
438 : V8_EXPORT_PRIVATE static Handle<ArrayList> Add(Isolate* isolate,
439 : Handle<ArrayList> array,
440 : Handle<Object> obj1,
441 : Handle<Object> obj2);
442 : static Handle<ArrayList> New(Isolate* isolate, int size);
443 :
444 : // Returns the number of elements in the list, not the allocated size, which
445 : // is length(). Lower and upper case length() return different results!
446 : inline int Length() const;
447 :
448 : // Sets the Length() as used by Elements(). Does not change the underlying
449 : // storage capacity, i.e., length().
450 : inline void SetLength(int length);
451 : inline Object Get(int index) const;
452 : inline ObjectSlot Slot(int index);
453 :
454 : // Set the element at index to obj. The underlying array must be large enough.
455 : // If you need to grow the ArrayList, use the static Add() methods instead.
456 : inline void Set(int index, Object obj,
457 : WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
458 :
459 : // Set the element at index to undefined. This does not change the Length().
460 : inline void Clear(int index, Object undefined);
461 :
462 : // Return a copy of the list of size Length() without the first entry. The
463 : // number returned by Length() is stored in the first entry.
464 : static Handle<FixedArray> Elements(Isolate* isolate, Handle<ArrayList> array);
465 : DECL_CAST(ArrayList)
466 :
467 : private:
468 : static Handle<ArrayList> EnsureSpace(Isolate* isolate,
469 : Handle<ArrayList> array, int length);
470 : static const int kLengthIndex = 0;
471 : static const int kFirstIndex = 1;
472 : OBJECT_CONSTRUCTORS(ArrayList, FixedArray);
473 : };
474 :
475 : enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
476 :
477 : template <SearchMode search_mode, typename T>
478 : inline int Search(T* array, Name name, int valid_entries = 0,
479 : int* out_insertion_index = nullptr);
480 :
481 : // ByteArray represents fixed sized byte arrays. Used for the relocation info
482 : // that is attached to code objects.
483 : class ByteArray : public FixedArrayBase {
484 : public:
485 : inline int Size();
486 :
487 : // Setter and getter.
488 : inline byte get(int index) const;
489 : inline void set(int index, byte value);
490 :
491 : // Copy in / copy out whole byte slices.
492 : inline void copy_out(int index, byte* buffer, int length);
493 : inline void copy_in(int index, const byte* buffer, int length);
494 :
495 : // Treat contents as an int array.
496 : inline int get_int(int index) const;
497 : inline void set_int(int index, int value);
498 :
499 : inline uint32_t get_uint32(int index) const;
500 : inline void set_uint32(int index, uint32_t value);
501 :
502 : // Clear uninitialized padding space. This ensures that the snapshot content
503 : // is deterministic.
504 : inline void clear_padding();
505 :
506 : static int SizeFor(int length) {
507 31430482 : return OBJECT_POINTER_ALIGN(kHeaderSize + length);
508 : }
509 : // We use byte arrays for free blocks in the heap. Given a desired size in
510 : // bytes that is a multiple of the word size and big enough to hold a byte
511 : // array, this function returns the number of elements a byte array should
512 : // have.
513 : static int LengthFor(int size_in_bytes) {
514 : DCHECK(IsAligned(size_in_bytes, kTaggedSize));
515 : DCHECK_GE(size_in_bytes, kHeaderSize);
516 57528 : return size_in_bytes - kHeaderSize;
517 : }
518 :
519 : // Returns data start address.
520 : inline byte* GetDataStartAddress();
521 : // Returns address of the past-the-end element.
522 : inline byte* GetDataEndAddress();
523 :
524 : inline int DataSize() const;
525 :
526 : // Returns a pointer to the ByteArray object for a given data start address.
527 : static inline ByteArray FromDataStartAddress(Address address);
528 :
529 : DECL_CAST(ByteArray)
530 :
531 : // Dispatched behavior.
532 : inline int ByteArraySize();
533 : DECL_PRINTER(ByteArray)
534 : DECL_VERIFIER(ByteArray)
535 :
536 : // Layout description.
537 : static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
538 :
539 : // Maximal length of a single ByteArray.
540 : static const int kMaxLength = kMaxSize - kHeaderSize;
541 : static_assert(Internals::IsValidSmi(kMaxLength),
542 : "ByteArray maxLength not a Smi");
543 :
544 : class BodyDescriptor;
545 :
546 : protected:
547 : // Special-purpose constructor for subclasses that have fast paths where
548 : // their ptr() is a Smi.
549 : inline ByteArray(Address ptr, AllowInlineSmiStorage allow_smi);
550 :
551 : OBJECT_CONSTRUCTORS(ByteArray, FixedArrayBase);
552 : };
553 :
554 : // Wrapper class for ByteArray which can store arbitrary C++ classes, as long
555 : // as they can be copied with memcpy.
556 : template <class T>
557 : class PodArray : public ByteArray {
558 : public:
559 : static Handle<PodArray<T>> New(
560 : Isolate* isolate, int length,
561 : AllocationType allocation = AllocationType::kYoung);
562 : void copy_out(int index, T* result) {
563 104 : ByteArray::copy_out(index * sizeof(T), reinterpret_cast<byte*>(result),
564 : sizeof(T));
565 : }
566 :
567 : void copy_in(int index, const T* buffer, int length) {
568 65709 : ByteArray::copy_in(index * sizeof(T), reinterpret_cast<const byte*>(buffer),
569 : length * sizeof(T));
570 : }
571 :
572 : T get(int index) {
573 : T result;
574 : copy_out(index, &result);
575 60837 : return result;
576 : }
577 :
578 : void set(int index, const T& value) { copy_in(index, &value, 1); }
579 :
580 : inline int length() const;
581 : DECL_CAST(PodArray<T>)
582 :
583 : OBJECT_CONSTRUCTORS(PodArray<T>, ByteArray);
584 : };
585 :
586 : class FixedTypedArrayBase : public FixedArrayBase {
587 : public:
588 : // [base_pointer]: Either points to the FixedTypedArrayBase itself or nullptr.
589 : DECL_ACCESSORS(base_pointer, Object)
590 :
591 : // [external_pointer]: Contains the offset between base_pointer and the start
592 : // of the data. If the base_pointer is a nullptr, the external_pointer
593 : // therefore points to the actual backing store.
594 : DECL_PRIMITIVE_ACCESSORS(external_pointer, void*)
595 :
596 : // Dispatched behavior.
597 : DECL_CAST(FixedTypedArrayBase)
598 :
599 : DEFINE_FIELD_OFFSET_CONSTANTS(FixedArrayBase::kHeaderSize,
600 : TORQUE_GENERATED_FIXED_TYPED_ARRAY_BASE_FIELDS)
601 : static const int kHeaderSize = kSize;
602 :
603 : #ifdef V8_COMPRESS_POINTERS
604 : // TODO(ishell, v8:8875): When pointer compression is enabled the kHeaderSize
605 : // is only kTaggedSize aligned but we can keep using unaligned access since
606 : // both x64 and arm64 architectures (where pointer compression supported)
607 : // allow unaligned access to doubles.
608 : STATIC_ASSERT(IsAligned(kHeaderSize, kTaggedSize));
609 : #else
610 : STATIC_ASSERT(IsAligned(kHeaderSize, kDoubleAlignment));
611 : #endif
612 :
613 : static const int kDataOffset = kHeaderSize;
614 :
615 : static const int kMaxElementSize = 8;
616 :
617 : #ifdef V8_HOST_ARCH_32_BIT
618 : static const size_t kMaxByteLength = std::numeric_limits<size_t>::max();
619 : #else
620 : static const size_t kMaxByteLength =
621 : static_cast<size_t>(Smi::kMaxValue) * kMaxElementSize;
622 : #endif // V8_HOST_ARCH_32_BIT
623 :
624 : static const size_t kMaxLength = Smi::kMaxValue;
625 :
626 : class BodyDescriptor;
627 :
628 : inline int size() const;
629 :
630 : static inline int TypedArraySize(InstanceType type, int length);
631 : inline int TypedArraySize(InstanceType type) const;
632 :
633 : // Use with care: returns raw pointer into heap.
634 : inline void* DataPtr();
635 :
636 : inline int DataSize() const;
637 :
638 : inline size_t ByteLength() const;
639 :
640 : static inline intptr_t ExternalPointerValueForOnHeapArray() {
641 : return FixedTypedArrayBase::kDataOffset - kHeapObjectTag;
642 : }
643 :
644 : static inline void* ExternalPointerPtrForOnHeapArray() {
645 : return reinterpret_cast<void*>(ExternalPointerValueForOnHeapArray());
646 : }
647 :
648 : private:
649 : static inline int ElementSize(InstanceType type);
650 :
651 : inline int DataSize(InstanceType type) const;
652 :
653 : OBJECT_CONSTRUCTORS(FixedTypedArrayBase, FixedArrayBase);
654 : };
655 :
656 : template <class Traits>
657 : class FixedTypedArray : public FixedTypedArrayBase {
658 : public:
659 : using ElementType = typename Traits::ElementType;
660 : static const InstanceType kInstanceType = Traits::kInstanceType;
661 :
662 : DECL_CAST(FixedTypedArray<Traits>)
663 :
664 : static inline ElementType get_scalar_from_data_ptr(void* data_ptr, int index);
665 : inline ElementType get_scalar(int index);
666 : static inline Handle<Object> get(Isolate* isolate, FixedTypedArray array,
667 : int index);
668 : inline void set(int index, ElementType value);
669 :
670 : static inline ElementType from(int value);
671 : static inline ElementType from(uint32_t value);
672 : static inline ElementType from(double value);
673 : static inline ElementType from(int64_t value);
674 : static inline ElementType from(uint64_t value);
675 :
676 : static inline ElementType FromHandle(Handle<Object> value,
677 : bool* lossless = nullptr);
678 :
679 : // This accessor applies the correct conversion from Smi, HeapNumber
680 : // and undefined.
681 : inline void SetValue(uint32_t index, Object value);
682 :
683 : DECL_PRINTER(FixedTypedArray)
684 : DECL_VERIFIER(FixedTypedArray)
685 :
686 : private:
687 : OBJECT_CONSTRUCTORS(FixedTypedArray, FixedTypedArrayBase);
688 : };
689 :
690 : #define FIXED_TYPED_ARRAY_TRAITS(Type, type, TYPE, elementType) \
691 : STATIC_ASSERT(sizeof(elementType) <= FixedTypedArrayBase::kMaxElementSize); \
692 : class Type##ArrayTraits { \
693 : public: /* NOLINT */ \
694 : using ElementType = elementType; \
695 : static const InstanceType kInstanceType = FIXED_##TYPE##_ARRAY_TYPE; \
696 : static const char* ArrayTypeName() { return "Fixed" #Type "Array"; } \
697 : static inline Handle<Object> ToHandle(Isolate* isolate, \
698 : elementType scalar); \
699 : static inline elementType defaultValue(); \
700 : }; \
701 : \
702 : using Fixed##Type##Array = FixedTypedArray<Type##ArrayTraits>;
703 :
704 : TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)
705 :
706 : #undef FIXED_TYPED_ARRAY_TRAITS
707 :
708 : class TemplateList : public FixedArray {
709 : public:
710 : static Handle<TemplateList> New(Isolate* isolate, int size);
711 : inline int length() const;
712 : inline Object get(int index) const;
713 : inline void set(int index, Object value);
714 : static Handle<TemplateList> Add(Isolate* isolate, Handle<TemplateList> list,
715 : Handle<Object> value);
716 : DECL_CAST(TemplateList)
717 : private:
718 : static const int kLengthIndex = 0;
719 : static const int kFirstElementIndex = kLengthIndex + 1;
720 :
721 : OBJECT_CONSTRUCTORS(TemplateList, FixedArray);
722 : };
723 :
724 : } // namespace internal
725 : } // namespace v8
726 :
727 : #include "src/objects/object-macros-undef.h"
728 :
729 : #endif // V8_OBJECTS_FIXED_ARRAY_H_
|