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