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