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 : typedef FlexibleWeakBodyDescriptor<HeapObject::kHeaderSize>
19 : WeakArrayBodyDescriptor;
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 : 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 : 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 : 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 : void CopyTo(int pos, FixedArray dest, int dest_pos, int len) const;
174 :
175 : // Garbage collection support.
176 5116 : static constexpr int SizeFor(int length) {
177 128883879 : return kHeaderSize + length * kTaggedSize;
178 : }
179 :
180 : // Code Generation support.
181 4204 : static constexpr int OffsetOfElementAt(int index) { return SizeFor(index); }
182 :
183 : // Garbage collection support.
184 : inline ObjectSlot RawFieldOfElementAt(int index);
185 :
186 : DECL_CAST(FixedArray)
187 : // Maximally allowed length of a FixedArray.
188 : static const int kMaxLength = (kMaxSize - kHeaderSize) / kTaggedSize;
189 : static_assert(Internals::IsValidSmi(kMaxLength),
190 : "FixedArray maxLength not a Smi");
191 :
192 : // Maximally allowed length for regular (non large object space) object.
193 : STATIC_ASSERT(kMaxRegularHeapObjectSize < kMaxSize);
194 : static const int kMaxRegularLength =
195 : (kMaxRegularHeapObjectSize - kHeaderSize) / kTaggedSize;
196 :
197 : // Dispatched behavior.
198 : DECL_PRINTER(FixedArray)
199 : DECL_VERIFIER(FixedArray)
200 :
201 : typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor;
202 :
203 : protected:
204 : // Set operation on FixedArray without using write barriers. Can
205 : // only be used for storing old space objects or smis.
206 : static inline void NoWriteBarrierSet(FixedArray array, int index,
207 : Object value);
208 :
209 : private:
210 : STATIC_ASSERT(kHeaderSize == Internals::kFixedArrayHeaderSize);
211 :
212 : inline void set_undefined(ReadOnlyRoots ro_roots, int index);
213 : inline void set_null(ReadOnlyRoots ro_roots, int index);
214 : inline void set_the_hole(ReadOnlyRoots ro_roots, int index);
215 :
216 1848 : OBJECT_CONSTRUCTORS(FixedArray, FixedArrayBase);
217 : };
218 :
219 : // FixedArray alias added only because of IsFixedArrayExact() predicate, which
220 : // checks for the exact instance type FIXED_ARRAY_TYPE instead of a range
221 : // check: [FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE].
222 : class FixedArrayExact final : public FixedArray {};
223 :
224 : // FixedDoubleArray describes fixed-sized arrays with element type double.
225 : class FixedDoubleArray : public FixedArrayBase {
226 : public:
227 : // Setter and getter for elements.
228 : inline double get_scalar(int index);
229 : inline uint64_t get_representation(int index);
230 : static inline Handle<Object> get(FixedDoubleArray array, int index,
231 : Isolate* isolate);
232 : inline void set(int index, double value);
233 : inline void set_the_hole(Isolate* isolate, int index);
234 : inline void set_the_hole(int index);
235 :
236 : // Checking for the hole.
237 : inline bool is_the_hole(Isolate* isolate, int index);
238 : inline bool is_the_hole(int index);
239 :
240 : // Garbage collection support.
241 : inline static int SizeFor(int length) {
242 1262764 : return kHeaderSize + length * kDoubleSize;
243 : }
244 :
245 : inline void MoveElements(Heap* heap, int dst_index, int src_index, int len,
246 : WriteBarrierMode mode);
247 :
248 : inline void FillWithHoles(int from, int to);
249 :
250 : // Code Generation support.
251 : static int OffsetOfElementAt(int index) { return SizeFor(index); }
252 :
253 : DECL_CAST(FixedDoubleArray)
254 :
255 : // Maximally allowed length of a FixedArray.
256 : static const int kMaxLength = (kMaxSize - kHeaderSize) / kDoubleSize;
257 : static_assert(Internals::IsValidSmi(kMaxLength),
258 : "FixedDoubleArray maxLength not a Smi");
259 :
260 : // Dispatched behavior.
261 : DECL_PRINTER(FixedDoubleArray)
262 : DECL_VERIFIER(FixedDoubleArray)
263 :
264 : class BodyDescriptor;
265 :
266 : OBJECT_CONSTRUCTORS(FixedDoubleArray, FixedArrayBase);
267 : };
268 :
269 : // WeakFixedArray describes fixed-sized arrays with element type
270 : // MaybeObject.
271 : class WeakFixedArray : public HeapObject {
272 : public:
273 : DECL_CAST(WeakFixedArray)
274 :
275 : inline MaybeObject Get(int index) const;
276 :
277 : // Setter that uses write barrier.
278 : inline void Set(int index, MaybeObject value);
279 :
280 : // Setter with explicit barrier mode.
281 : inline void Set(int index, MaybeObject value, WriteBarrierMode mode);
282 :
283 56 : static constexpr int SizeFor(int length) {
284 12892217 : return kHeaderSize + length * kTaggedSize;
285 : }
286 :
287 : DECL_INT_ACCESSORS(length)
288 :
289 : // Get and set the length using acquire loads and release stores.
290 : inline int synchronized_length() const;
291 : inline void synchronized_set_length(int value);
292 :
293 : // Gives access to raw memory which stores the array's data.
294 : inline MaybeObjectSlot data_start();
295 :
296 : inline MaybeObjectSlot RawFieldOfElementAt(int index);
297 :
298 : DECL_PRINTER(WeakFixedArray)
299 : DECL_VERIFIER(WeakFixedArray)
300 :
301 : typedef WeakArrayBodyDescriptor BodyDescriptor;
302 :
303 : // Layout description.
304 : #define WEAK_FIXED_ARRAY_FIELDS(V) \
305 : V(kLengthOffset, kTaggedSize) \
306 : /* Header size. */ \
307 : V(kHeaderSize, 0)
308 :
309 : DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
310 : WEAK_FIXED_ARRAY_FIELDS)
311 : #undef WEAK_FIXED_ARRAY_FIELDS
312 :
313 : static const int kMaxLength =
314 : (FixedArray::kMaxSize - kHeaderSize) / kTaggedSize;
315 : static_assert(Internals::IsValidSmi(kMaxLength),
316 : "WeakFixedArray maxLength not a Smi");
317 :
318 : protected:
319 : static int OffsetOfElementAt(int index) {
320 232970291 : return kHeaderSize + index * kTaggedSize;
321 : }
322 :
323 : private:
324 : friend class Heap;
325 :
326 : static const int kFirstIndex = 1;
327 :
328 112 : OBJECT_CONSTRUCTORS(WeakFixedArray, HeapObject);
329 : };
330 :
331 : // WeakArrayList is like a WeakFixedArray with static convenience methods for
332 : // adding more elements. length() returns the number of elements in the list and
333 : // capacity() returns the allocated size. The number of elements is stored at
334 : // kLengthOffset and is updated with every insertion. The array grows
335 : // dynamically with O(1) amortized insertion.
336 : class WeakArrayList : public HeapObject {
337 : public:
338 : NEVER_READ_ONLY_SPACE
339 : DECL_CAST(WeakArrayList)
340 : DECL_VERIFIER(WeakArrayList)
341 : DECL_PRINTER(WeakArrayList)
342 :
343 : static Handle<WeakArrayList> AddToEnd(Isolate* isolate,
344 : Handle<WeakArrayList> array,
345 : const MaybeObjectHandle& value);
346 :
347 : inline MaybeObject Get(int index) const;
348 :
349 : // Set the element at index to obj. The underlying array must be large enough.
350 : // If you need to grow the WeakArrayList, use the static AddToEnd() method
351 : // instead.
352 : inline void Set(int index, MaybeObject value,
353 : WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
354 :
355 56 : static constexpr int SizeForCapacity(int capacity) {
356 5583960 : return kHeaderSize + capacity * kTaggedSize;
357 : }
358 :
359 : // Gives access to raw memory which stores the array's data.
360 : inline MaybeObjectSlot data_start();
361 :
362 : bool IsFull();
363 :
364 : DECL_INT_ACCESSORS(capacity)
365 : DECL_INT_ACCESSORS(length)
366 :
367 : // Get and set the capacity using acquire loads and release stores.
368 : inline int synchronized_capacity() const;
369 : inline void synchronized_set_capacity(int value);
370 :
371 :
372 : // Layout description.
373 : #define WEAK_ARRAY_LIST_FIELDS(V) \
374 : V(kCapacityOffset, kTaggedSize) \
375 : V(kLengthOffset, kTaggedSize) \
376 : /* Header size. */ \
377 : V(kHeaderSize, 0)
378 :
379 : DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, WEAK_ARRAY_LIST_FIELDS)
380 : #undef WEAK_ARRAY_LIST_FIELDS
381 :
382 : typedef WeakArrayBodyDescriptor BodyDescriptor;
383 :
384 : static const int kMaxCapacity =
385 : (FixedArray::kMaxSize - kHeaderSize) / kTaggedSize;
386 :
387 : static Handle<WeakArrayList> EnsureSpace(
388 : Isolate* isolate, Handle<WeakArrayList> array, int length,
389 : AllocationType allocation = AllocationType::kYoung);
390 :
391 : // Returns the number of non-cleaned weak references in the array.
392 : int CountLiveWeakReferences() const;
393 :
394 : // Returns whether an entry was found and removed. Will move the elements
395 : // around in the array - this method can only be used in cases where the user
396 : // doesn't care about the indices! Users should make sure there are no
397 : // duplicates.
398 : bool RemoveOne(const MaybeObjectHandle& value);
399 :
400 : class Iterator;
401 :
402 : private:
403 : static int OffsetOfElementAt(int index) {
404 66586514 : return kHeaderSize + index * kTaggedSize;
405 : }
406 :
407 448 : OBJECT_CONSTRUCTORS(WeakArrayList, HeapObject);
408 : };
409 :
410 : class WeakArrayList::Iterator {
411 : public:
412 135701 : explicit Iterator(WeakArrayList array) : index_(0), array_(array) {}
413 :
414 : inline HeapObject Next();
415 :
416 : private:
417 : int index_;
418 : WeakArrayList array_;
419 : #ifdef DEBUG
420 : DisallowHeapAllocation no_gc_;
421 : #endif // DEBUG
422 : DISALLOW_COPY_AND_ASSIGN(Iterator);
423 : };
424 :
425 : // Generic array grows dynamically with O(1) amortized insertion.
426 : //
427 : // ArrayList is a FixedArray with static convenience methods for adding more
428 : // elements. The Length() method returns the number of elements in the list, not
429 : // the allocated size. The number of elements is stored at kLengthIndex and is
430 : // updated with every insertion. The elements of the ArrayList are stored in the
431 : // underlying FixedArray starting at kFirstIndex.
432 : class ArrayList : public FixedArray {
433 : public:
434 : static Handle<ArrayList> Add(Isolate* isolate, Handle<ArrayList> array,
435 : Handle<Object> obj);
436 : static Handle<ArrayList> Add(Isolate* isolate, Handle<ArrayList> array,
437 : Handle<Object> obj1, Handle<Object> obj2);
438 : static Handle<ArrayList> New(Isolate* isolate, int size);
439 :
440 : // Returns the number of elements in the list, not the allocated size, which
441 : // is length(). Lower and upper case length() return different results!
442 : inline int Length() const;
443 :
444 : // Sets the Length() as used by Elements(). Does not change the underlying
445 : // storage capacity, i.e., length().
446 : inline void SetLength(int length);
447 : inline Object Get(int index) const;
448 : inline ObjectSlot Slot(int index);
449 :
450 : // Set the element at index to obj. The underlying array must be large enough.
451 : // If you need to grow the ArrayList, use the static Add() methods instead.
452 : inline void Set(int index, Object obj,
453 : WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
454 :
455 : // Set the element at index to undefined. This does not change the Length().
456 : inline void Clear(int index, Object undefined);
457 :
458 : // Return a copy of the list of size Length() without the first entry. The
459 : // number returned by Length() is stored in the first entry.
460 : static Handle<FixedArray> Elements(Isolate* isolate, Handle<ArrayList> array);
461 : DECL_CAST(ArrayList)
462 :
463 : private:
464 : static Handle<ArrayList> EnsureSpace(Isolate* isolate,
465 : Handle<ArrayList> array, int length);
466 : static const int kLengthIndex = 0;
467 : static const int kFirstIndex = 1;
468 : OBJECT_CONSTRUCTORS(ArrayList, FixedArray);
469 : };
470 :
471 : enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
472 :
473 : template <SearchMode search_mode, typename T>
474 : inline int Search(T* array, Name name, int valid_entries = 0,
475 : int* out_insertion_index = nullptr);
476 :
477 : // ByteArray represents fixed sized byte arrays. Used for the relocation info
478 : // that is attached to code objects.
479 : class ByteArray : public FixedArrayBase {
480 : public:
481 : inline int Size();
482 :
483 : // Setter and getter.
484 : inline byte get(int index) const;
485 : inline void set(int index, byte value);
486 :
487 : // Copy in / copy out whole byte slices.
488 : inline void copy_out(int index, byte* buffer, int length);
489 : inline void copy_in(int index, const byte* buffer, int length);
490 :
491 : // Treat contents as an int array.
492 : inline int get_int(int index) const;
493 : inline void set_int(int index, int value);
494 :
495 : inline uint32_t get_uint32(int index) const;
496 : inline void set_uint32(int index, uint32_t value);
497 :
498 : // Clear uninitialized padding space. This ensures that the snapshot content
499 : // is deterministic.
500 : inline void clear_padding();
501 :
502 56 : static int SizeFor(int length) {
503 30398102 : return OBJECT_POINTER_ALIGN(kHeaderSize + length);
504 : }
505 : // We use byte arrays for free blocks in the heap. Given a desired size in
506 : // bytes that is a multiple of the word size and big enough to hold a byte
507 : // array, this function returns the number of elements a byte array should
508 : // have.
509 : static int LengthFor(int size_in_bytes) {
510 : DCHECK(IsAligned(size_in_bytes, kTaggedSize));
511 : DCHECK_GE(size_in_bytes, kHeaderSize);
512 43037 : return size_in_bytes - kHeaderSize;
513 : }
514 :
515 : // Returns data start address.
516 : inline byte* GetDataStartAddress();
517 : // Returns address of the past-the-end element.
518 : inline byte* GetDataEndAddress();
519 :
520 : inline int DataSize() const;
521 :
522 : // Returns a pointer to the ByteArray object for a given data start address.
523 : static inline ByteArray FromDataStartAddress(Address address);
524 :
525 : DECL_CAST(ByteArray)
526 :
527 : // Dispatched behavior.
528 : inline int ByteArraySize();
529 : DECL_PRINTER(ByteArray)
530 : DECL_VERIFIER(ByteArray)
531 :
532 : // Layout description.
533 : static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
534 :
535 : // Maximal length of a single ByteArray.
536 : static const int kMaxLength = kMaxSize - kHeaderSize;
537 : static_assert(Internals::IsValidSmi(kMaxLength),
538 : "ByteArray maxLength not a Smi");
539 :
540 : class BodyDescriptor;
541 :
542 : protected:
543 : // Special-purpose constructor for subclasses that have fast paths where
544 : // their ptr() is a Smi.
545 : inline ByteArray(Address ptr, AllowInlineSmiStorage allow_smi);
546 :
547 224 : OBJECT_CONSTRUCTORS(ByteArray, FixedArrayBase);
548 : };
549 :
550 : // Wrapper class for ByteArray which can store arbitrary C++ classes, as long
551 : // as they can be copied with memcpy.
552 : template <class T>
553 : class PodArray : public ByteArray {
554 : public:
555 : static Handle<PodArray<T>> New(
556 : Isolate* isolate, int length,
557 : AllocationType allocation = AllocationType::kYoung);
558 : void copy_out(int index, T* result) {
559 90 : ByteArray::copy_out(index * sizeof(T), reinterpret_cast<byte*>(result),
560 : sizeof(T));
561 : }
562 :
563 : void copy_in(int index, const T* buffer, int length) {
564 64795 : ByteArray::copy_in(index * sizeof(T), reinterpret_cast<const byte*>(buffer),
565 : length * sizeof(T));
566 : }
567 :
568 : T get(int index) {
569 : T result;
570 : copy_out(index, &result);
571 60895 : return result;
572 : }
573 :
574 : void set(int index, const T& value) { copy_in(index, &value, 1); }
575 :
576 : inline int length() const;
577 : DECL_CAST(PodArray<T>)
578 :
579 : OBJECT_CONSTRUCTORS(PodArray<T>, ByteArray);
580 : };
581 :
582 : class FixedTypedArrayBase : public FixedArrayBase {
583 : public:
584 : // [base_pointer]: Either points to the FixedTypedArrayBase itself or nullptr.
585 : DECL_ACCESSORS(base_pointer, Object)
586 :
587 : // [external_pointer]: Contains the offset between base_pointer and the start
588 : // of the data. If the base_pointer is a nullptr, the external_pointer
589 : // therefore points to the actual backing store.
590 : DECL_PRIMITIVE_ACCESSORS(external_pointer, void*)
591 :
592 : // Dispatched behavior.
593 : DECL_CAST(FixedTypedArrayBase)
594 :
595 : DEFINE_FIELD_OFFSET_CONSTANTS(FixedArrayBase::kHeaderSize,
596 : TORQUE_GENERATED_FIXED_TYPED_ARRAY_BASE_FIELDS)
597 : static const int kHeaderSize = kSize;
598 :
599 : #ifdef V8_COMPRESS_POINTERS
600 : // TODO(ishell, v8:8875): When pointer compression is enabled the kHeaderSize
601 : // is only kTaggedSize aligned but we can keep using unaligned access since
602 : // both x64 and arm64 architectures (where pointer compression supported)
603 : // allow unaligned access to doubles.
604 : STATIC_ASSERT(IsAligned(kHeaderSize, kTaggedSize));
605 : #else
606 : STATIC_ASSERT(IsAligned(kHeaderSize, kDoubleAlignment));
607 : #endif
608 :
609 : static const int kDataOffset = kHeaderSize;
610 :
611 : static const int kMaxElementSize = 8;
612 :
613 : #ifdef V8_HOST_ARCH_32_BIT
614 : static const size_t kMaxByteLength = std::numeric_limits<size_t>::max();
615 : #else
616 : static const size_t kMaxByteLength =
617 : static_cast<size_t>(Smi::kMaxValue) * kMaxElementSize;
618 : #endif // V8_HOST_ARCH_32_BIT
619 :
620 : static const size_t kMaxLength = Smi::kMaxValue;
621 :
622 : class BodyDescriptor;
623 :
624 : inline int size() const;
625 :
626 : static inline int TypedArraySize(InstanceType type, int length);
627 : inline int TypedArraySize(InstanceType type) const;
628 :
629 : // Use with care: returns raw pointer into heap.
630 : inline void* DataPtr();
631 :
632 : inline int DataSize() const;
633 :
634 : inline size_t ByteLength() const;
635 :
636 784 : static inline intptr_t ExternalPointerValueForOnHeapArray() {
637 784 : return FixedTypedArrayBase::kDataOffset - kHeapObjectTag;
638 : }
639 :
640 616 : static inline void* ExternalPointerPtrForOnHeapArray() {
641 616 : return reinterpret_cast<void*>(ExternalPointerValueForOnHeapArray());
642 : }
643 :
644 : private:
645 : static inline int ElementSize(InstanceType type);
646 :
647 : inline int DataSize(InstanceType type) const;
648 :
649 2464 : OBJECT_CONSTRUCTORS(FixedTypedArrayBase, FixedArrayBase);
650 : };
651 :
652 : template <class Traits>
653 : class FixedTypedArray : public FixedTypedArrayBase {
654 : public:
655 : typedef typename Traits::ElementType ElementType;
656 : static const InstanceType kInstanceType = Traits::kInstanceType;
657 :
658 : DECL_CAST(FixedTypedArray<Traits>)
659 :
660 : static inline ElementType get_scalar_from_data_ptr(void* data_ptr, int index);
661 : inline ElementType get_scalar(int index);
662 : static inline Handle<Object> get(Isolate* isolate, FixedTypedArray array,
663 : int index);
664 : inline void set(int index, ElementType value);
665 :
666 : static inline ElementType from(int value);
667 : static inline ElementType from(uint32_t value);
668 : static inline ElementType from(double value);
669 : static inline ElementType from(int64_t value);
670 : static inline ElementType from(uint64_t value);
671 :
672 : static inline ElementType FromHandle(Handle<Object> value,
673 : bool* lossless = nullptr);
674 :
675 : // This accessor applies the correct conversion from Smi, HeapNumber
676 : // and undefined.
677 : inline void SetValue(uint32_t index, Object value);
678 :
679 : DECL_PRINTER(FixedTypedArray)
680 : DECL_VERIFIER(FixedTypedArray)
681 :
682 : private:
683 : OBJECT_CONSTRUCTORS(FixedTypedArray, FixedTypedArrayBase);
684 : };
685 :
686 : #define FIXED_TYPED_ARRAY_TRAITS(Type, type, TYPE, elementType) \
687 : STATIC_ASSERT(sizeof(elementType) <= FixedTypedArrayBase::kMaxElementSize); \
688 : class Type##ArrayTraits { \
689 : public: /* NOLINT */ \
690 : typedef elementType ElementType; \
691 : static const InstanceType kInstanceType = FIXED_##TYPE##_ARRAY_TYPE; \
692 : static const char* ArrayTypeName() { return "Fixed" #Type "Array"; } \
693 : static inline Handle<Object> ToHandle(Isolate* isolate, \
694 : elementType scalar); \
695 : static inline elementType defaultValue(); \
696 : }; \
697 : \
698 : typedef FixedTypedArray<Type##ArrayTraits> Fixed##Type##Array;
699 :
700 : TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)
701 :
702 : #undef FIXED_TYPED_ARRAY_TRAITS
703 :
704 : class TemplateList : public FixedArray {
705 : public:
706 : static Handle<TemplateList> New(Isolate* isolate, int size);
707 : inline int length() const;
708 : inline Object get(int index) const;
709 : inline void set(int index, Object value);
710 : static Handle<TemplateList> Add(Isolate* isolate, Handle<TemplateList> list,
711 : Handle<Object> value);
712 : DECL_CAST(TemplateList)
713 : private:
714 : static const int kLengthIndex = 0;
715 : static const int kFirstElementIndex = kLengthIndex + 1;
716 :
717 56 : OBJECT_CONSTRUCTORS(TemplateList, FixedArray);
718 : };
719 :
720 : } // namespace internal
721 : } // namespace v8
722 :
723 : #include "src/objects/object-macros-undef.h"
724 :
725 : #endif // V8_OBJECTS_FIXED_ARRAY_H_
|