LCOV - code coverage report
Current view: top level - src/objects - fixed-array-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 279 305 91.5 %
Date: 2019-01-20 Functions: 141 166 84.9 %

          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_INL_H_
       6             : #define V8_OBJECTS_FIXED_ARRAY_INL_H_
       7             : 
       8             : #include "src/objects/fixed-array.h"
       9             : 
      10             : #include "src/conversions.h"
      11             : #include "src/handles-inl.h"
      12             : #include "src/heap/heap-write-barrier-inl.h"
      13             : #include "src/objects/bigint.h"
      14             : #include "src/objects/heap-number-inl.h"
      15             : #include "src/objects/map.h"
      16             : #include "src/objects/maybe-object-inl.h"
      17             : #include "src/objects/oddball.h"
      18             : #include "src/objects/slots.h"
      19             : 
      20             : // Has to be the last include (doesn't have include guards):
      21             : #include "src/objects/object-macros.h"
      22             : 
      23             : namespace v8 {
      24             : namespace internal {
      25             : 
      26   790349948 : OBJECT_CONSTRUCTORS_IMPL(FixedArrayBase, HeapObject)
      27  1451789908 : OBJECT_CONSTRUCTORS_IMPL(FixedArray, FixedArrayBase)
      28    51532906 : OBJECT_CONSTRUCTORS_IMPL(FixedDoubleArray, FixedArrayBase)
      29    76167526 : OBJECT_CONSTRUCTORS_IMPL(FixedTypedArrayBase, FixedArrayBase)
      30       11072 : OBJECT_CONSTRUCTORS_IMPL(ArrayList, FixedArray)
      31   795739842 : OBJECT_CONSTRUCTORS_IMPL(ByteArray, FixedArrayBase)
      32    16866860 : OBJECT_CONSTRUCTORS_IMPL(TemplateList, FixedArray)
      33    70058256 : OBJECT_CONSTRUCTORS_IMPL(WeakFixedArray, HeapObject)
      34    23982328 : OBJECT_CONSTRUCTORS_IMPL(WeakArrayList, HeapObject)
      35             : 
      36             : FixedArrayBase::FixedArrayBase(Address ptr, AllowInlineSmiStorage allow_smi)
      37             :     : HeapObject(ptr, allow_smi) {
      38             :   SLOW_DCHECK(
      39             :       (allow_smi == AllowInlineSmiStorage::kAllowBeingASmi && IsSmi()) ||
      40             :       IsFixedArrayBase());
      41             : }
      42             : 
      43             : ByteArray::ByteArray(Address ptr, AllowInlineSmiStorage allow_smi)
      44             :     : FixedArrayBase(ptr, allow_smi) {
      45             :   SLOW_DCHECK(
      46             :       (allow_smi == AllowInlineSmiStorage::kAllowBeingASmi && IsSmi()) ||
      47             :       IsByteArray());
      48             : }
      49             : 
      50             : NEVER_READ_ONLY_SPACE_IMPL(WeakArrayList)
      51             : 
      52        5536 : CAST_ACCESSOR(ArrayList)
      53   397921062 : CAST_ACCESSOR(ByteArray)
      54   725094482 : CAST_ACCESSOR(FixedArray)
      55   395174829 : CAST_ACCESSOR(FixedArrayBase)
      56    25765545 : CAST_ACCESSOR(FixedDoubleArray)
      57    38083876 : CAST_ACCESSOR(FixedTypedArrayBase)
      58     8433430 : CAST_ACCESSOR(TemplateList)
      59    35029136 : CAST_ACCESSOR(WeakFixedArray)
      60    11991162 : CAST_ACCESSOR(WeakArrayList)
      61             : 
      62  1894920937 : SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
      63   483567284 : SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
      64   163519893 : SMI_ACCESSORS(WeakFixedArray, length, kLengthOffset)
      65    36079330 : SYNCHRONIZED_SMI_ACCESSORS(WeakFixedArray, length, kLengthOffset)
      66             : 
      67    35346725 : SMI_ACCESSORS(WeakArrayList, capacity, kCapacityOffset)
      68    13151643 : SYNCHRONIZED_SMI_ACCESSORS(WeakArrayList, capacity, kCapacityOffset)
      69   123664900 : SMI_ACCESSORS(WeakArrayList, length, kLengthOffset)
      70             : 
      71             : Object FixedArrayBase::unchecked_synchronized_length() const {
      72    11629081 :   return ACQUIRE_READ_FIELD(this, kLengthOffset);
      73             : }
      74             : 
      75   132368500 : ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset)
      76             : 
      77             : ObjectSlot FixedArray::GetFirstElementAddress() {
      78             :   return RawField(OffsetOfElementAt(0));
      79             : }
      80             : 
      81             : bool FixedArray::ContainsOnlySmisOrHoles() {
      82             :   Object the_hole = GetReadOnlyRoots().the_hole_value();
      83             :   ObjectSlot current = GetFirstElementAddress();
      84             :   for (int i = 0; i < length(); ++i, ++current) {
      85             :     Object candidate = *current;
      86             :     if (!candidate->IsSmi() && candidate != the_hole) return false;
      87             :   }
      88             :   return true;
      89             : }
      90             : 
      91      467580 : Object FixedArray::get(int index) const {
      92             :   DCHECK(index >= 0 && index < this->length());
      93  6235337460 :   return RELAXED_READ_FIELD(this, kHeaderSize + index * kTaggedSize);
      94             : }
      95             : 
      96    31129485 : Handle<Object> FixedArray::get(FixedArray array, int index, Isolate* isolate) {
      97    31129487 :   return handle(array->get(index), isolate);
      98             : }
      99             : 
     100             : template <class T>
     101     4744851 : MaybeHandle<T> FixedArray::GetValue(Isolate* isolate, int index) const {
     102     4744851 :   Object obj = get(index);
     103     4744851 :   if (obj->IsUndefined(isolate)) return MaybeHandle<T>();
     104      830457 :   return Handle<T>(T::cast(obj), isolate);
     105             : }
     106             : 
     107             : template <class T>
     108      297313 : Handle<T> FixedArray::GetValueChecked(Isolate* isolate, int index) const {
     109      297313 :   Object obj = get(index);
     110      297318 :   CHECK(!obj->IsUndefined(isolate));
     111      297320 :   return Handle<T>(T::cast(obj), isolate);
     112             : }
     113             : 
     114   310985008 : bool FixedArray::is_the_hole(Isolate* isolate, int index) {
     115   621970016 :   return get(index)->IsTheHole(isolate);
     116             : }
     117             : 
     118         608 : void FixedArray::set(int index, Smi value) {
     119             :   DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map());
     120             :   DCHECK_LT(index, this->length());
     121             :   DCHECK(Object(value).IsSmi());
     122   134410104 :   int offset = kHeaderSize + index * kTaggedSize;
     123   236924763 :   RELAXED_WRITE_FIELD(this, offset, value);
     124         608 : }
     125             : 
     126   470483318 : void FixedArray::set(int index, Object value) {
     127             :   DCHECK_NE(GetReadOnlyRoots().fixed_cow_array_map(), map());
     128             :   DCHECK(IsFixedArray());
     129             :   DCHECK_GE(index, 0);
     130             :   DCHECK_LT(index, this->length());
     131   470483318 :   int offset = kHeaderSize + index * kTaggedSize;
     132   470483318 :   RELAXED_WRITE_FIELD(*this, offset, value);
     133   940966688 :   WRITE_BARRIER(*this, offset, value);
     134   470483384 : }
     135             : 
     136  1278726184 : void FixedArray::set(int index, Object value, WriteBarrierMode mode) {
     137             :   DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map());
     138             :   DCHECK_GE(index, 0);
     139             :   DCHECK_LT(index, this->length());
     140  1278726184 :   int offset = kHeaderSize + index * kTaggedSize;
     141  1278726184 :   RELAXED_WRITE_FIELD(*this, offset, value);
     142  2780563281 :   CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode);
     143  1278726110 : }
     144             : 
     145             : void FixedArray::NoWriteBarrierSet(FixedArray array, int index, Object value) {
     146             :   DCHECK_NE(array->map(), array->GetReadOnlyRoots().fixed_cow_array_map());
     147             :   DCHECK_GE(index, 0);
     148             :   DCHECK_LT(index, array->length());
     149             :   DCHECK(!Heap::InNewSpace(value));
     150   378057698 :   RELAXED_WRITE_FIELD(array, kHeaderSize + index * kTaggedSize, value);
     151             : }
     152             : 
     153   357484032 : void FixedArray::set_undefined(int index) {
     154   357484032 :   set_undefined(GetReadOnlyRoots(), index);
     155   357484032 : }
     156             : 
     157        1476 : void FixedArray::set_undefined(Isolate* isolate, int index) {
     158        1476 :   set_undefined(ReadOnlyRoots(isolate), index);
     159        1476 : }
     160             : 
     161   357485508 : void FixedArray::set_undefined(ReadOnlyRoots ro_roots, int index) {
     162             :   FixedArray::NoWriteBarrierSet(*this, index, ro_roots.undefined_value());
     163   357485508 : }
     164             : 
     165         529 : void FixedArray::set_null(int index) { set_null(GetReadOnlyRoots(), index); }
     166             : 
     167             : void FixedArray::set_null(Isolate* isolate, int index) {
     168             :   set_null(ReadOnlyRoots(isolate), index);
     169             : }
     170             : 
     171         529 : void FixedArray::set_null(ReadOnlyRoots ro_roots, int index) {
     172             :   FixedArray::NoWriteBarrierSet(*this, index, ro_roots.null_value());
     173         529 : }
     174             : 
     175    11329514 : void FixedArray::set_the_hole(int index) {
     176    11329514 :   set_the_hole(GetReadOnlyRoots(), index);
     177    11329515 : }
     178             : 
     179     8121485 : void FixedArray::set_the_hole(Isolate* isolate, int index) {
     180     8121485 :   set_the_hole(ReadOnlyRoots(isolate), index);
     181     8121485 : }
     182             : 
     183    19451000 : void FixedArray::set_the_hole(ReadOnlyRoots ro_roots, int index) {
     184             :   FixedArray::NoWriteBarrierSet(*this, index, ro_roots.the_hole_value());
     185    19451000 : }
     186             : 
     187             : void FixedArray::FillWithHoles(int from, int to) {
     188    11280093 :   for (int i = from; i < to; i++) {
     189    11280092 :     set_the_hole(i);
     190             :   }
     191             : }
     192             : 
     193           0 : ObjectSlot FixedArray::data_start() {
     194           0 :   return RawField(OffsetOfElementAt(0));
     195             : }
     196             : 
     197      140344 : ObjectSlot FixedArray::RawFieldOfElementAt(int index) {
     198      140344 :   return RawField(OffsetOfElementAt(index));
     199             : }
     200             : 
     201             : void FixedArray::MoveElements(Heap* heap, int dst_index, int src_index, int len,
     202             :                               WriteBarrierMode mode) {
     203             :   DisallowHeapAllocation no_gc;
     204        1345 :   heap->MoveElements(*this, dst_index, src_index, len, mode);
     205             : }
     206             : 
     207             : // Perform a binary search in a fixed array.
     208             : template <SearchMode search_mode, typename T>
     209    20537070 : int BinarySearch(T* array, Name name, int valid_entries,
     210             :                  int* out_insertion_index) {
     211             :   DCHECK(search_mode == ALL_ENTRIES || out_insertion_index == nullptr);
     212             :   int low = 0;
     213    20537070 :   int high = array->number_of_entries() - 1;
     214             :   uint32_t hash = name->hash_field();
     215             :   int limit = high;
     216             : 
     217             :   DCHECK(low <= high);
     218             : 
     219   127196623 :   while (low != high) {
     220    86122558 :     int mid = low + (high - low) / 2;
     221    59371450 :     Name mid_name = array->GetSortedKey(mid);
     222             :     uint32_t mid_hash = mid_name->hash_field();
     223             : 
     224    86122483 :     if (mid_hash >= hash) {
     225             :       high = mid;
     226             :     } else {
     227    48574672 :       low = mid + 1;
     228             :     }
     229             :   }
     230             : 
     231           0 :   for (; low <= limit; ++low) {
     232             :     int sort_index = array->GetSortedKeyIndex(low);
     233    20536968 :     Name entry = array->GetKey(sort_index);
     234             :     uint32_t current_hash = entry->hash_field();
     235    20536958 :     if (current_hash != hash) {
     236      120985 :       if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
     237       60734 :         *out_insertion_index = sort_index + (current_hash > hash ? 0 : 1);
     238             :       }
     239             :       return T::kNotFound;
     240             :     }
     241    11190475 :     if (entry == name) {
     242     4118730 :       if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
     243     3954622 :         return sort_index;
     244             :       }
     245             :       return T::kNotFound;
     246             :     }
     247             :   }
     248             : 
     249           0 :   if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
     250           0 :     *out_insertion_index = limit + 1;
     251             :   }
     252             :   return T::kNotFound;
     253             : }
     254             : 
     255             : // Perform a linear search in this fixed array. len is the number of entry
     256             : // indices that are valid.
     257             : template <SearchMode search_mode, typename T>
     258    13038776 : int LinearSearch(T* array, Name name, int valid_entries,
     259             :                  int* out_insertion_index) {
     260    13038776 :   if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
     261             :     uint32_t hash = name->hash_field();
     262             :     int len = array->number_of_entries();
     263      394398 :     for (int number = 0; number < len; number++) {
     264             :       int sorted_index = array->GetSortedKeyIndex(number);
     265      344816 :       Name entry = array->GetKey(sorted_index);
     266             :       uint32_t current_hash = entry->hash_field();
     267      344819 :       if (current_hash > hash) {
     268      105450 :         *out_insertion_index = sorted_index;
     269      105450 :         return T::kNotFound;
     270             :       }
     271      239369 :       if (entry == name) return sorted_index;
     272             :     }
     273       49582 :     *out_insertion_index = len;
     274       49582 :     return T::kNotFound;
     275             :   } else {
     276             :     DCHECK_LE(valid_entries, array->number_of_entries());
     277             :     DCHECK_NULL(out_insertion_index);  // Not supported here.
     278    65318046 :     for (int number = 0; number < valid_entries; number++) {
     279   183936745 :       if (array->GetKey(number) == name) return number;
     280             :     }
     281             :     return T::kNotFound;
     282             :   }
     283             : }
     284             : 
     285             : template <SearchMode search_mode, typename T>
     286    61543621 : int Search(T* array, Name name, int valid_entries, int* out_insertion_index) {
     287             :   SLOW_DCHECK(array->IsSortedNoDuplicates());
     288             : 
     289    61543621 :   if (valid_entries == 0) {
     290      434674 :     if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
     291      241147 :       *out_insertion_index = 0;
     292             :     }
     293             :     return T::kNotFound;
     294             :   }
     295             : 
     296             :   // Fast case: do linear search for small arrays.
     297             :   const int kMaxElementsForLinearSearch = 8;
     298    61108976 :   if (valid_entries <= kMaxElementsForLinearSearch) {
     299             :     return LinearSearch<search_mode>(array, name, valid_entries,
     300    40572012 :                                      out_insertion_index);
     301             :   }
     302             : 
     303             :   // Slow case: perform binary search.
     304             :   return BinarySearch<search_mode>(array, name, valid_entries,
     305    20536977 :                                    out_insertion_index);
     306             : }
     307             : 
     308         656 : double FixedDoubleArray::get_scalar(int index) {
     309             :   DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() &&
     310             :          map() != GetReadOnlyRoots().fixed_array_map());
     311             :   DCHECK(index >= 0 && index < this->length());
     312             :   DCHECK(!is_the_hole(index));
     313     7493425 :   return READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
     314             : }
     315             : 
     316             : uint64_t FixedDoubleArray::get_representation(int index) {
     317             :   DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() &&
     318             :          map() != GetReadOnlyRoots().fixed_array_map());
     319             :   DCHECK(index >= 0 && index < this->length());
     320    27571346 :   int offset = kHeaderSize + index * kDoubleSize;
     321    27571346 :   return READ_UINT64_FIELD(this, offset);
     322             : }
     323             : 
     324     8673395 : Handle<Object> FixedDoubleArray::get(FixedDoubleArray array, int index,
     325             :                                      Isolate* isolate) {
     326     8673395 :   if (array->is_the_hole(index)) {
     327     1297705 :     return isolate->factory()->the_hole_value();
     328             :   } else {
     329     7375690 :     return isolate->factory()->NewNumber(array->get_scalar(index));
     330             :   }
     331             : }
     332             : 
     333             : void FixedDoubleArray::set(int index, double value) {
     334             :   DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() &&
     335             :          map() != GetReadOnlyRoots().fixed_array_map());
     336    12129488 :   int offset = kHeaderSize + index * kDoubleSize;
     337    12122402 :   if (std::isnan(value)) {
     338        2157 :     WRITE_DOUBLE_FIELD(this, offset, std::numeric_limits<double>::quiet_NaN());
     339             :   } else {
     340    12127356 :     WRITE_DOUBLE_FIELD(this, offset, value);
     341             :   }
     342             :   DCHECK(!is_the_hole(index));
     343             : }
     344             : 
     345             : void FixedDoubleArray::set_the_hole(Isolate* isolate, int index) {
     346             :   set_the_hole(index);
     347             : }
     348             : 
     349             : void FixedDoubleArray::set_the_hole(int index) {
     350             :   DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() &&
     351             :          map() != GetReadOnlyRoots().fixed_array_map());
     352    44358680 :   int offset = kHeaderSize + index * kDoubleSize;
     353    44358680 :   WRITE_UINT64_FIELD(this, offset, kHoleNanInt64);
     354             : }
     355             : 
     356             : bool FixedDoubleArray::is_the_hole(Isolate* isolate, int index) {
     357             :   return is_the_hole(index);
     358             : }
     359             : 
     360             : bool FixedDoubleArray::is_the_hole(int index) {
     361           0 :   return get_representation(index) == kHoleNanInt64;
     362             : }
     363             : 
     364          16 : void FixedDoubleArray::MoveElements(Heap* heap, int dst_index, int src_index,
     365             :                                     int len, WriteBarrierMode mode) {
     366             :   DCHECK_EQ(SKIP_WRITE_BARRIER, mode);
     367             :   double* data_start =
     368          16 :       reinterpret_cast<double*>(FIELD_ADDR(*this, kHeaderSize));
     369          16 :   MemMove(data_start + dst_index, data_start + src_index, len * kDoubleSize);
     370          16 : }
     371             : 
     372             : void FixedDoubleArray::FillWithHoles(int from, int to) {
     373      381916 :   for (int i = from; i < to; i++) {
     374             :     set_the_hole(i);
     375             :   }
     376             : }
     377             : 
     378   272920612 : MaybeObject WeakFixedArray::Get(int index) const {
     379             :   DCHECK(index >= 0 && index < this->length());
     380   545841224 :   return RELAXED_READ_WEAK_FIELD(*this, OffsetOfElementAt(index));
     381             : }
     382             : 
     383    34885267 : void WeakFixedArray::Set(int index, MaybeObject value) {
     384             :   DCHECK_GE(index, 0);
     385             :   DCHECK_LT(index, length());
     386             :   int offset = OffsetOfElementAt(index);
     387    34885267 :   RELAXED_WRITE_WEAK_FIELD(*this, offset, value);
     388    69770568 :   WEAK_WRITE_BARRIER(*this, offset, value);
     389    34885309 : }
     390             : 
     391     2621842 : void WeakFixedArray::Set(int index, MaybeObject value, WriteBarrierMode mode) {
     392             :   DCHECK_GE(index, 0);
     393             :   DCHECK_LT(index, length());
     394             :   int offset = OffsetOfElementAt(index);
     395     2621842 :   RELAXED_WRITE_WEAK_FIELD(*this, offset, value);
     396     7865526 :   CONDITIONAL_WEAK_WRITE_BARRIER(*this, offset, value, mode);
     397     2621842 : }
     398             : 
     399             : MaybeObjectSlot WeakFixedArray::data_start() {
     400             :   return RawMaybeWeakField(kHeaderSize);
     401             : }
     402             : 
     403             : MaybeObjectSlot WeakFixedArray::RawFieldOfElementAt(int index) {
     404             :   return RawMaybeWeakField(OffsetOfElementAt(index));
     405             : }
     406             : 
     407    31861926 : MaybeObject WeakArrayList::Get(int index) const {
     408             :   DCHECK(index >= 0 && index < this->capacity());
     409    63723852 :   return RELAXED_READ_WEAK_FIELD(*this, OffsetOfElementAt(index));
     410             : }
     411             : 
     412    36417787 : void WeakArrayList::Set(int index, MaybeObject value, WriteBarrierMode mode) {
     413             :   DCHECK_GE(index, 0);
     414             :   DCHECK_LT(index, this->capacity());
     415             :   int offset = OffsetOfElementAt(index);
     416    36417787 :   RELAXED_WRITE_WEAK_FIELD(*this, offset, value);
     417    85529532 :   CONDITIONAL_WEAK_WRITE_BARRIER(*this, offset, value, mode);
     418    36417813 : }
     419             : 
     420             : MaybeObjectSlot WeakArrayList::data_start() {
     421             :   return RawMaybeWeakField(kHeaderSize);
     422             : }
     423             : 
     424     5200954 : HeapObject WeakArrayList::Iterator::Next() {
     425     5200954 :   if (!array_.is_null()) {
     426    10427072 :     while (index_ < array_->length()) {
     427     5209278 :       MaybeObject item = array_->Get(index_++);
     428             :       DCHECK(item->IsWeakOrCleared());
     429    10405924 :       if (!item->IsCleared()) return item->GetHeapObjectAssumeWeak();
     430             :     }
     431        4258 :     array_ = WeakArrayList();
     432             :   }
     433        4308 :   return HeapObject();
     434             : }
     435             : 
     436       22838 : int ArrayList::Length() const {
     437       22838 :   if (FixedArray::cast(*this)->length() == 0) return 0;
     438       22416 :   return Smi::ToInt(FixedArray::cast(*this)->get(kLengthIndex));
     439             : }
     440             : 
     441        2780 : void ArrayList::SetLength(int length) {
     442        2780 :   return FixedArray::cast(*this)->set(kLengthIndex, Smi::FromInt(length));
     443             : }
     444             : 
     445       19146 : Object ArrayList::Get(int index) const {
     446       38292 :   return FixedArray::cast(*this)->get(kFirstIndex + index);
     447             : }
     448             : 
     449             : ObjectSlot ArrayList::Slot(int index) {
     450             :   return RawField(OffsetOfElementAt(kFirstIndex + index));
     451             : }
     452             : 
     453        2325 : void ArrayList::Set(int index, Object obj, WriteBarrierMode mode) {
     454        4650 :   FixedArray::cast(*this)->set(kFirstIndex + index, obj, mode);
     455        2325 : }
     456             : 
     457           5 : void ArrayList::Clear(int index, Object undefined) {
     458             :   DCHECK(undefined->IsUndefined());
     459             :   FixedArray::cast(*this)->set(kFirstIndex + index, undefined,
     460          10 :                                SKIP_WRITE_BARRIER);
     461           5 : }
     462             : 
     463    35213215 : int ByteArray::Size() { return RoundUp(length() + kHeaderSize, kTaggedSize); }
     464             : 
     465             : byte ByteArray::get(int index) const {
     466             :   DCHECK(index >= 0 && index < this->length());
     467    61152898 :   return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
     468             : }
     469             : 
     470             : void ByteArray::set(int index, byte value) {
     471             :   DCHECK(index >= 0 && index < this->length());
     472    11486770 :   WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
     473             : }
     474             : 
     475             : void ByteArray::copy_in(int index, const byte* buffer, int length) {
     476             :   DCHECK(index >= 0 && length >= 0 && length <= kMaxInt - index &&
     477             :          index + length <= this->length());
     478      133013 :   Address dst_addr = FIELD_ADDR(this, kHeaderSize + index * kCharSize);
     479      195916 :   memcpy(reinterpret_cast<void*>(dst_addr), buffer, length);
     480             : }
     481             : 
     482             : void ByteArray::copy_out(int index, byte* buffer, int length) {
     483             :   DCHECK(index >= 0 && length >= 0 && length <= kMaxInt - index &&
     484             :          index + length <= this->length());
     485   304044371 :   Address src_addr = FIELD_ADDR(this, kHeaderSize + index * kCharSize);
     486   304044371 :   memcpy(buffer, reinterpret_cast<void*>(src_addr), length);
     487             : }
     488             : 
     489             : int ByteArray::get_int(int index) const {
     490             :   DCHECK(index >= 0 && index < this->length() / kIntSize);
     491        2568 :   return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
     492             : }
     493             : 
     494             : void ByteArray::set_int(int index, int value) {
     495             :   DCHECK(index >= 0 && index < this->length() / kIntSize);
     496        1530 :   WRITE_INT_FIELD(this, kHeaderSize + index * kIntSize, value);
     497             : }
     498             : 
     499     1016815 : uint32_t ByteArray::get_uint32(int index) const {
     500             :   DCHECK(index >= 0 && index < this->length() / kUInt32Size);
     501     1016815 :   return READ_UINT32_FIELD(this, kHeaderSize + index * kUInt32Size);
     502             : }
     503             : 
     504      149491 : void ByteArray::set_uint32(int index, uint32_t value) {
     505             :   DCHECK(index >= 0 && index < this->length() / kUInt32Size);
     506      149491 :   WRITE_UINT32_FIELD(this, kHeaderSize + index * kUInt32Size, value);
     507      149491 : }
     508             : 
     509     7457593 : void ByteArray::clear_padding() {
     510     7457599 :   int data_size = length() + kHeaderSize;
     511    14915209 :   memset(reinterpret_cast<void*>(address() + data_size), 0, Size() - data_size);
     512     7457610 : }
     513             : 
     514             : ByteArray ByteArray::FromDataStartAddress(Address address) {
     515             :   DCHECK_TAG_ALIGNED(address);
     516             :   return ByteArray::cast(Object(address - kHeaderSize + kHeapObjectTag));
     517             : }
     518             : 
     519         874 : int ByteArray::DataSize() const { return RoundUp(length(), kTaggedSize); }
     520             : 
     521             : int ByteArray::ByteArraySize() { return SizeFor(this->length()); }
     522             : 
     523         394 : byte* ByteArray::GetDataStartAddress() {
     524   432599116 :   return reinterpret_cast<byte*>(address() + kHeaderSize);
     525             : }
     526             : 
     527   169578651 : byte* ByteArray::GetDataEndAddress() {
     528   169154875 :   return GetDataStartAddress() + length();
     529             : }
     530             : 
     531             : template <class T>
     532     1039200 : PodArray<T>::PodArray(Address ptr) : ByteArray(ptr) {}
     533             : 
     534             : template <class T>
     535             : PodArray<T> PodArray<T>::cast(Object object) {
     536      519598 :   return PodArray<T>(object.ptr());
     537             : }
     538             : 
     539             : // static
     540             : template <class T>
     541       13568 : Handle<PodArray<T>> PodArray<T>::New(Isolate* isolate, int length,
     542             :                                      PretenureFlag pretenure) {
     543             :   return Handle<PodArray<T>>::cast(
     544       13676 :       isolate->factory()->NewByteArray(length * sizeof(T), pretenure));
     545             : }
     546             : 
     547             : template <class T>
     548             : int PodArray<T>::length() const {
     549           0 :   return ByteArray::length() / sizeof(T);
     550             : }
     551             : 
     552             : void* FixedTypedArrayBase::external_pointer() const {
     553     5570899 :   intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
     554        3334 :   return reinterpret_cast<void*>(ptr);
     555             : }
     556             : 
     557             : void FixedTypedArrayBase::set_external_pointer(void* value,
     558             :                                                WriteBarrierMode mode) {
     559       13977 :   intptr_t ptr = reinterpret_cast<intptr_t>(value);
     560       13982 :   WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
     561             : }
     562             : 
     563         342 : void* FixedTypedArrayBase::DataPtr() {
     564             :   return reinterpret_cast<void*>(
     565    11134010 :       base_pointer()->ptr() + reinterpret_cast<intptr_t>(external_pointer()));
     566             : }
     567             : 
     568      327769 : int FixedTypedArrayBase::ElementSize(InstanceType type) {
     569             :   int element_size;
     570      327769 :   switch (type) {
     571             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
     572             :   case FIXED_##TYPE##_ARRAY_TYPE:                 \
     573             :     element_size = sizeof(ctype);                 \
     574             :     break;
     575             : 
     576       24899 :     TYPED_ARRAYS(TYPED_ARRAY_CASE)
     577             : #undef TYPED_ARRAY_CASE
     578             :     default:
     579           0 :       UNREACHABLE();
     580             :   }
     581      327769 :   return element_size;
     582             : }
     583             : 
     584      780398 : int FixedTypedArrayBase::DataSize(InstanceType type) const {
     585     1560788 :   if (base_pointer() == Smi::kZero) return 0;
     586      327766 :   return length() * ElementSize(type);
     587             : }
     588             : 
     589      219707 : int FixedTypedArrayBase::DataSize() const {
     590      219707 :   return DataSize(map()->instance_type());
     591             : }
     592             : 
     593             : size_t FixedTypedArrayBase::ByteLength() const {
     594             :   return static_cast<size_t>(length()) *
     595             :          static_cast<size_t>(ElementSize(map()->instance_type()));
     596             : }
     597             : 
     598             : int FixedTypedArrayBase::size() const {
     599      193909 :   return OBJECT_POINTER_ALIGN(kDataOffset + DataSize());
     600             : }
     601             : 
     602             : int FixedTypedArrayBase::TypedArraySize(InstanceType type) const {
     603      560667 :   return OBJECT_POINTER_ALIGN(kDataOffset + DataSize(type));
     604             : }
     605             : 
     606             : // static
     607             : int FixedTypedArrayBase::TypedArraySize(InstanceType type, int length) {
     608             :   return OBJECT_POINTER_ALIGN(kDataOffset + length * ElementSize(type));
     609             : }
     610             : 
     611             : uint8_t Uint8ArrayTraits::defaultValue() { return 0; }
     612             : 
     613             : uint8_t Uint8ClampedArrayTraits::defaultValue() { return 0; }
     614             : 
     615             : int8_t Int8ArrayTraits::defaultValue() { return 0; }
     616             : 
     617             : uint16_t Uint16ArrayTraits::defaultValue() { return 0; }
     618             : 
     619             : int16_t Int16ArrayTraits::defaultValue() { return 0; }
     620             : 
     621             : uint32_t Uint32ArrayTraits::defaultValue() { return 0; }
     622             : 
     623             : int32_t Int32ArrayTraits::defaultValue() { return 0; }
     624             : 
     625             : float Float32ArrayTraits::defaultValue() {
     626             :   return std::numeric_limits<float>::quiet_NaN();
     627             : }
     628             : 
     629             : double Float64ArrayTraits::defaultValue() {
     630             :   return std::numeric_limits<double>::quiet_NaN();
     631             : }
     632             : 
     633             : template <class Traits>
     634      426554 : typename Traits::ElementType FixedTypedArray<Traits>::get_scalar(int index) {
     635             :   DCHECK((index >= 0) && (index < this->length()));
     636      853108 :   return FixedTypedArray<Traits>::get_scalar_from_data_ptr(DataPtr(), index);
     637             : }
     638             : 
     639             : // static
     640             : template <class Traits>
     641             : typename Traits::ElementType FixedTypedArray<Traits>::get_scalar_from_data_ptr(
     642             :     void* data_ptr, int index) {
     643             :   typename Traits::ElementType* ptr = reinterpret_cast<ElementType*>(data_ptr);
     644             :   // The JavaScript memory model allows for racy reads and writes to a
     645             :   // SharedArrayBuffer's backing store, which will always be a FixedTypedArray.
     646             :   // ThreadSanitizer will catch these racy accesses and warn about them, so we
     647             :   // disable TSAN for these reads and writes using annotations.
     648             :   //
     649             :   // We don't use relaxed atomics here, as it is not a requirement of the
     650             :   // JavaScript memory model to have tear-free reads of overlapping accesses,
     651             :   // and using relaxed atomics may introduce overhead.
     652             :   TSAN_ANNOTATE_IGNORE_READS_BEGIN;
     653      442403 :   auto result = ptr[index];
     654             :   TSAN_ANNOTATE_IGNORE_READS_END;
     655             :   return result;
     656             : }
     657             : 
     658             : template <class Traits>
     659     5116609 : void FixedTypedArray<Traits>::set(int index, ElementType value) {
     660    10233218 :   CHECK((index >= 0) && (index < this->length()));
     661             :   // See the comment in FixedTypedArray<Traits>::get_scalar.
     662     5116609 :   auto* ptr = reinterpret_cast<ElementType*>(DataPtr());
     663             :   TSAN_ANNOTATE_IGNORE_WRITES_BEGIN;
     664     5116609 :   ptr[index] = value;
     665             :   TSAN_ANNOTATE_IGNORE_WRITES_END;
     666     5116609 : }
     667             : 
     668             : template <class Traits>
     669             : typename Traits::ElementType FixedTypedArray<Traits>::from(int value) {
     670     2504250 :   return static_cast<ElementType>(value);
     671             : }
     672             : 
     673             : template <>
     674             : inline uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from(int value) {
     675       24553 :   if (value < 0) return 0;
     676       24688 :   if (value > 0xFF) return 0xFF;
     677       24274 :   return static_cast<uint8_t>(value);
     678             : }
     679             : 
     680             : template <>
     681           0 : inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(int value) {
     682           0 :   UNREACHABLE();
     683             : }
     684             : 
     685             : template <>
     686           0 : inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(int value) {
     687           0 :   UNREACHABLE();
     688             : }
     689             : 
     690             : template <class Traits>
     691             : typename Traits::ElementType FixedTypedArray<Traits>::from(uint32_t value) {
     692        1314 :   return static_cast<ElementType>(value);
     693             : }
     694             : 
     695             : template <>
     696             : inline uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from(uint32_t value) {
     697             :   // We need this special case for Uint32 -> Uint8Clamped, because the highest
     698             :   // Uint32 values will be negative as an int, clamping to 0, rather than 255.
     699         198 :   if (value > 0xFF) return 0xFF;
     700         117 :   return static_cast<uint8_t>(value);
     701             : }
     702             : 
     703             : template <>
     704           0 : inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(uint32_t value) {
     705           0 :   UNREACHABLE();
     706             : }
     707             : 
     708             : template <>
     709           0 : inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(uint32_t value) {
     710           0 :   UNREACHABLE();
     711             : }
     712             : 
     713             : template <class Traits>
     714             : typename Traits::ElementType FixedTypedArray<Traits>::from(double value) {
     715      348208 :   return static_cast<ElementType>(DoubleToInt32(value));
     716             : }
     717             : 
     718             : template <>
     719             : inline uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from(double value) {
     720             :   // Handle NaNs and less than zero values which clamp to zero.
     721       93857 :   if (!(value > 0)) return 0;
     722       92521 :   if (value > 0xFF) return 0xFF;
     723       91792 :   return static_cast<uint8_t>(lrint(value));
     724             : }
     725             : 
     726             : template <>
     727           0 : inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(double value) {
     728           0 :   UNREACHABLE();
     729             : }
     730             : 
     731             : template <>
     732           0 : inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(double value) {
     733           0 :   UNREACHABLE();
     734             : }
     735             : 
     736             : template <>
     737             : inline float FixedTypedArray<Float32ArrayTraits>::from(double value) {
     738      134455 :   return static_cast<float>(value);
     739             : }
     740             : 
     741             : template <>
     742             : inline double FixedTypedArray<Float64ArrayTraits>::from(double value) {
     743             :   return value;
     744             : }
     745             : 
     746             : template <class Traits>
     747           0 : typename Traits::ElementType FixedTypedArray<Traits>::from(int64_t value) {
     748           0 :   UNREACHABLE();
     749             : }
     750             : 
     751             : template <class Traits>
     752           0 : typename Traits::ElementType FixedTypedArray<Traits>::from(uint64_t value) {
     753           0 :   UNREACHABLE();
     754             : }
     755             : 
     756             : template <>
     757             : inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(int64_t value) {
     758             :   return value;
     759             : }
     760             : 
     761             : template <>
     762             : inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(uint64_t value) {
     763             :   return value;
     764             : }
     765             : 
     766             : template <>
     767             : inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::from(int64_t value) {
     768           0 :   return static_cast<uint64_t>(value);
     769             : }
     770             : 
     771             : template <>
     772             : inline int64_t FixedTypedArray<BigInt64ArrayTraits>::from(uint64_t value) {
     773           0 :   return static_cast<int64_t>(value);
     774             : }
     775             : 
     776             : template <class Traits>
     777        3708 : typename Traits::ElementType FixedTypedArray<Traits>::FromHandle(
     778             :     Handle<Object> value, bool* lossless) {
     779        7416 :   if (value->IsSmi()) {
     780        6264 :     return from(Smi::ToInt(*value));
     781             :   }
     782             :   DCHECK(value->IsHeapNumber());
     783             :   return from(HeapNumber::cast(*value)->value());
     784             : }
     785             : 
     786             : template <>
     787         252 : inline int64_t FixedTypedArray<BigInt64ArrayTraits>::FromHandle(
     788             :     Handle<Object> value, bool* lossless) {
     789             :   DCHECK(value->IsBigInt());
     790         252 :   return BigInt::cast(*value)->AsInt64(lossless);
     791             : }
     792             : 
     793             : template <>
     794         252 : inline uint64_t FixedTypedArray<BigUint64ArrayTraits>::FromHandle(
     795             :     Handle<Object> value, bool* lossless) {
     796             :   DCHECK(value->IsBigInt());
     797         252 :   return BigInt::cast(*value)->AsUint64(lossless);
     798             : }
     799             : 
     800             : template <class Traits>
     801      228883 : Handle<Object> FixedTypedArray<Traits>::get(Isolate* isolate,
     802             :                                             FixedTypedArray<Traits> array,
     803             :                                             int index) {
     804      632496 :   return Traits::ToHandle(isolate, array->get_scalar(index));
     805             : }
     806             : 
     807             : template <class Traits>
     808     2661233 : void FixedTypedArray<Traits>::SetValue(uint32_t index, Object value) {
     809             :   ElementType cast_value = Traits::defaultValue();
     810     2661233 :   if (value->IsSmi()) {
     811      255417 :     int int_value = Smi::ToInt(value);
     812             :     cast_value = from(int_value);
     813     2405816 :   } else if (value->IsHeapNumber()) {
     814             :     double double_value = HeapNumber::cast(value)->value();
     815             :     cast_value = from(double_value);
     816             :   } else {
     817             :     // Clamp undefined to the default value. All other types have been
     818             :     // converted to a number type further up in the call chain.
     819             :     DCHECK(value->IsUndefined());
     820             :   }
     821     2661233 :   set(index, cast_value);
     822     2661233 : }
     823             : 
     824             : template <>
     825         675 : inline void FixedTypedArray<BigInt64ArrayTraits>::SetValue(uint32_t index,
     826             :                                                            Object value) {
     827             :   DCHECK(value->IsBigInt());
     828         675 :   set(index, BigInt::cast(value)->AsInt64());
     829         675 : }
     830             : 
     831             : template <>
     832         450 : inline void FixedTypedArray<BigUint64ArrayTraits>::SetValue(uint32_t index,
     833             :                                                             Object value) {
     834             :   DCHECK(value->IsBigInt());
     835         450 :   set(index, BigInt::cast(value)->AsUint64());
     836         450 : }
     837             : 
     838       86924 : Handle<Object> Uint8ArrayTraits::ToHandle(Isolate* isolate, uint8_t scalar) {
     839       86924 :   return handle(Smi::FromInt(scalar), isolate);
     840             : }
     841             : 
     842        2241 : Handle<Object> Uint8ClampedArrayTraits::ToHandle(Isolate* isolate,
     843             :                                                  uint8_t scalar) {
     844        2241 :   return handle(Smi::FromInt(scalar), isolate);
     845             : }
     846             : 
     847        5522 : Handle<Object> Int8ArrayTraits::ToHandle(Isolate* isolate, int8_t scalar) {
     848        5522 :   return handle(Smi::FromInt(scalar), isolate);
     849             : }
     850             : 
     851       75627 : Handle<Object> Uint16ArrayTraits::ToHandle(Isolate* isolate, uint16_t scalar) {
     852       75627 :   return handle(Smi::FromInt(scalar), isolate);
     853             : }
     854             : 
     855        4416 : Handle<Object> Int16ArrayTraits::ToHandle(Isolate* isolate, int16_t scalar) {
     856        4416 :   return handle(Smi::FromInt(scalar), isolate);
     857             : }
     858             : 
     859             : Handle<Object> Uint32ArrayTraits::ToHandle(Isolate* isolate, uint32_t scalar) {
     860       75180 :   return isolate->factory()->NewNumberFromUint(scalar);
     861             : }
     862             : 
     863             : Handle<Object> Int32ArrayTraits::ToHandle(Isolate* isolate, int32_t scalar) {
     864        4414 :   return isolate->factory()->NewNumberFromInt(scalar);
     865             : }
     866             : 
     867             : Handle<Object> Float32ArrayTraits::ToHandle(Isolate* isolate, float scalar) {
     868       74849 :   return isolate->factory()->NewNumber(scalar);
     869             : }
     870             : 
     871             : Handle<Object> Float64ArrayTraits::ToHandle(Isolate* isolate, double scalar) {
     872       74359 :   return isolate->factory()->NewNumber(scalar);
     873             : }
     874             : 
     875             : Handle<Object> BigInt64ArrayTraits::ToHandle(Isolate* isolate, int64_t scalar) {
     876          45 :   return BigInt::FromInt64(isolate, scalar);
     877             : }
     878             : 
     879             : Handle<Object> BigUint64ArrayTraits::ToHandle(Isolate* isolate,
     880             :                                               uint64_t scalar) {
     881          36 :   return BigInt::FromUint64(isolate, scalar);
     882             : }
     883             : 
     884             : // static
     885             : template <class Traits>
     886             : STATIC_CONST_MEMBER_DEFINITION const InstanceType
     887             :     FixedTypedArray<Traits>::kInstanceType;
     888             : 
     889             : template <class Traits>
     890     1264910 : FixedTypedArray<Traits>::FixedTypedArray(Address ptr)
     891             :     : FixedTypedArrayBase(ptr) {
     892             :   DCHECK(IsHeapObject() && map()->instance_type() == Traits::kInstanceType);
     893     1264910 : }
     894             : 
     895             : template <class Traits>
     896             : FixedTypedArray<Traits> FixedTypedArray<Traits>::cast(Object object) {
     897     1264910 :   return FixedTypedArray<Traits>(object.ptr());
     898             : }
     899             : 
     900     6432534 : int TemplateList::length() const {
     901     6432534 :   return Smi::ToInt(FixedArray::cast(*this)->get(kLengthIndex));
     902             : }
     903             : 
     904     8412485 : Object TemplateList::get(int index) const {
     905    16824970 :   return FixedArray::cast(*this)->get(kFirstElementIndex + index);
     906             : }
     907             : 
     908         151 : void TemplateList::set(int index, Object value) {
     909         302 :   FixedArray::cast(*this)->set(kFirstElementIndex + index, value);
     910         151 : }
     911             : 
     912             : }  // namespace internal
     913             : }  // namespace v8
     914             : 
     915             : #include "src/objects/object-macros-undef.h"
     916             : 
     917             : #endif  // V8_OBJECTS_FIXED_ARRAY_INL_H_

Generated by: LCOV version 1.10