13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/elements.h" 669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arguments.h" 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/conversions.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/factory.h" 103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#include "src/isolate-inl.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/messages.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/objects-inl.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/utils.h" 143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Each concrete ElementsAccessor can handle exactly one ElementsKind, 163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// several abstract ElementsAccessor classes are used to allow sharing 173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// common code. 183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Inheritance hierarchy: 203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - ElementsAccessorBase (abstract) 213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - FastElementsAccessor (abstract) 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FastSmiOrObjectElementsAccessor 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FastPackedSmiElementsAccessor 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FastHoleySmiElementsAccessor 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FastPackedObjectElementsAccessor 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FastHoleyObjectElementsAccessor 273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - FastDoubleElementsAccessor 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FastPackedDoubleElementsAccessor 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FastHoleyDoubleElementsAccessor 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - TypedElementsAccessor: template, with instantiations: 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FixedUint8ElementsAccessor 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FixedInt8ElementsAccessor 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FixedUint16ElementsAccessor 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FixedInt16ElementsAccessor 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FixedUint32ElementsAccessor 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FixedInt32ElementsAccessor 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FixedFloat32ElementsAccessor 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FixedFloat64ElementsAccessor 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - FixedUint8ClampedElementsAccessor 403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - DictionaryElementsAccessor 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - SloppyArgumentsElementsAccessor 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// - FastSloppyArgumentsElementsAccessor 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// - SlowSloppyArgumentsElementsAccessor 44109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// - StringWrapperElementsAccessor 45109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// - FastStringWrapperElementsAccessor 46109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// - SlowStringWrapperElementsAccessor 473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochnamespace v8 { 4969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochnamespace internal { 5069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 5169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace { 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kPackedSizeNotKnown = -1; 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum Where { AT_START, AT_END }; 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// First argument in list is the accessor class, the second argument is the 613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// accessor ElementsKind, and the third is the backing store class. Use the 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// fast element handler for smi-only arrays. The implementation is currently 633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// identical. Note that the order must match that of the ElementsKind enum for 643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// the |accessor_array[]| below to work. 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ELEMENTS_LIST(V) \ 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \ 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, FixedArray) \ 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \ 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \ 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, FixedDoubleArray) \ 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \ 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedDoubleArray) \ 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, SeededNumberDictionary) \ 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FastSloppyArgumentsElementsAccessor, FAST_SLOPPY_ARGUMENTS_ELEMENTS, \ 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray) \ 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(SlowSloppyArgumentsElementsAccessor, SLOW_SLOPPY_ARGUMENTS_ELEMENTS, \ 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray) \ 78109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch V(FastStringWrapperElementsAccessor, FAST_STRING_WRAPPER_ELEMENTS, \ 79109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArray) \ 80109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch V(SlowStringWrapperElementsAccessor, SLOW_STRING_WRAPPER_ELEMENTS, \ 81109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArray) \ 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FixedUint8ElementsAccessor, UINT8_ELEMENTS, FixedUint8Array) \ 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FixedInt8ElementsAccessor, INT8_ELEMENTS, FixedInt8Array) \ 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FixedUint16ElementsAccessor, UINT16_ELEMENTS, FixedUint16Array) \ 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FixedInt16ElementsAccessor, INT16_ELEMENTS, FixedInt16Array) \ 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FixedUint32ElementsAccessor, UINT32_ELEMENTS, FixedUint32Array) \ 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FixedInt32ElementsAccessor, INT32_ELEMENTS, FixedInt32Array) \ 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FixedFloat32ElementsAccessor, FLOAT32_ELEMENTS, FixedFloat32Array) \ 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FixedFloat64ElementsAccessor, FLOAT64_ELEMENTS, FixedFloat64Array) \ 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \ 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedUint8ClampedArray) 923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate<ElementsKind Kind> class ElementsKindTraits { 943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef FixedArrayBase BackingStore; 963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define ELEMENTS_TRAITS(Class, KindParam, Store) \ 993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate<> class ElementsKindTraits<KindParam> { \ 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: /* NOLINT */ \ 1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const ElementsKind Kind = KindParam; \ 1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef Store BackingStore; \ 1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochELEMENTS_LIST(ELEMENTS_TRAITS) 1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef ELEMENTS_TRAITS 1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMUST_USE_RESULT 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMaybeHandle<Object> ThrowArrayLengthRangeError(Isolate* isolate) { 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kInvalidArrayLength), 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object); 1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CopyObjectToObjectElements(FixedArrayBase* from_base, 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind from_kind, uint32_t from_start, 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArrayBase* to_base, ElementsKind to_kind, 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t to_start, int raw_copy_size) { 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(to_base->map() != 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch from_base->GetIsolate()->heap()->fixed_cow_array_map()); 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_allocation; 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size = raw_copy_size; 1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size < 0) { 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd || 1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch copy_size = Min(from_base->length() - from_start, 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to_base->length() - to_start); 1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int start = to_start + copy_size; 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = to_base->length() - start; 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (length > 0) { 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap = from_base->GetHeap(); 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemsetPointer(FixedArray::cast(to_base)->data_start() + start, 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->the_hole_value(), length); 1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() && 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (copy_size + static_cast<int>(from_start)) <= from_base->length()); 1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (copy_size == 0) return; 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* from = FixedArray::cast(from_base); 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* to = FixedArray::cast(to_base); 143bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(IsFastSmiOrObjectElementsKind(from_kind)); 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsFastSmiOrObjectElementsKind(to_kind)); 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch WriteBarrierMode write_barrier_mode = 147bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch (IsFastObjectElementsKind(from_kind) && IsFastObjectElementsKind(to_kind)) 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? UPDATE_WRITE_BARRIER 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : SKIP_WRITE_BARRIER; 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < copy_size; i++) { 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* value = from->get(from_start + i); 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch to->set(to_start + i, value, write_barrier_mode); 1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CopyDictionaryToObjectElements( 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArrayBase* from_base, uint32_t from_start, FixedArrayBase* to_base, 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind to_kind, uint32_t to_start, int raw_copy_size) { 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_allocation; 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base); 1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size = raw_copy_size; 1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size < 0) { 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd || 1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size = from->max_number_key() + 1 - from_start; 1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int start = to_start + copy_size; 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = to_base->length() - start; 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (length > 0) { 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap = from->GetHeap(); 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemsetPointer(FixedArray::cast(to_base)->data_start() + start, 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->the_hole_value(), length); 1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(to_base != from_base); 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsFastSmiOrObjectElementsKind(to_kind)); 1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (copy_size == 0) return; 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* to = FixedArray::cast(to_base); 1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_length = to->length(); 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (to_start + copy_size > to_length) { 1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size = to_length - to_start; 1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch WriteBarrierMode write_barrier_mode = IsFastObjectElementsKind(to_kind) 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? UPDATE_WRITE_BARRIER 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : SKIP_WRITE_BARRIER; 18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Isolate* isolate = from->GetIsolate(); 1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < copy_size; i++) { 19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int entry = from->FindEntry(isolate, i + from_start); 1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry != SeededNumberDictionary::kNotFound) { 1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* value = from->ValueAt(entry); 19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(!value->IsTheHole(isolate)); 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch to->set(i + to_start, value, write_barrier_mode); 1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 19662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch to->set_the_hole(isolate, i + to_start); 1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// NOTE: this method violates the handlified function signature convention: 203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// raw pointer parameters in the function that allocates. 204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// See ElementsAccessorBase::CopyElements() for details. 205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void CopyDoubleToObjectElements(FixedArrayBase* from_base, 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t from_start, 207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FixedArrayBase* to_base, 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t to_start, int raw_copy_size) { 2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size = raw_copy_size; 2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size < 0) { 211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DisallowHeapAllocation no_allocation; 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd || 2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch copy_size = Min(from_base->length() - from_start, 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to_base->length() - to_start); 2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Also initialize the area that will be copied over since HeapNumber 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // allocation below can cause an incremental marking step, requiring all 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // existing heap objects to be propertly initialized. 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int start = to_start; 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = to_base->length() - start; 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (length > 0) { 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap = from_base->GetHeap(); 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MemsetPointer(FixedArray::cast(to_base)->data_start() + start, 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->the_hole_value(), length); 2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() && 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (copy_size + static_cast<int>(from_start)) <= from_base->length()); 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (copy_size == 0) return; 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // From here on, the code below could actually allocate. Therefore the raw 235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // values are wrapped into handles. 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = from_base->GetIsolate(); 237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedDoubleArray> from(FixedDoubleArray::cast(from_base), isolate); 238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArray> to(FixedArray::cast(to_base), isolate); 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 240109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Use an outer loop to not waste too much time on creating HandleScopes. 241109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // On the other hand we might overflow a single handle scope depending on 242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // the copy_size. 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = 0; 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (offset < copy_size) { 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch offset += 100; 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = offset - 100; i < offset && i < copy_size; ++i) { 248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> value = 249109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedDoubleArray::get(*from, i + from_start, isolate); 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to->set(i + to_start, *value, UPDATE_WRITE_BARRIER); 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CopyDoubleToDoubleElements(FixedArrayBase* from_base, 2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArrayBase* to_base, 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t to_start, int raw_copy_size) { 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_allocation; 2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size = raw_copy_size; 2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size < 0) { 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd || 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch copy_size = Min(from_base->length() - from_start, 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to_base->length() - to_start); 2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = to_start + copy_size; i < to_base->length(); ++i) { 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray::cast(to_base)->set_the_hole(i); 2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() && 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (copy_size + static_cast<int>(from_start)) <= from_base->length()); 2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (copy_size == 0) return; 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray* from = FixedDoubleArray::cast(from_base); 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray* to = FixedDoubleArray::cast(to_base); 2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address to_address = to->address() + FixedDoubleArray::kHeaderSize; 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address from_address = from->address() + FixedDoubleArray::kHeaderSize; 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to_address += kDoubleSize * to_start; 2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch from_address += kDoubleSize * from_start; 2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int words_per_double = (kDoubleSize / kPointerSize); 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CopyWords(reinterpret_cast<Object**>(to_address), 2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Object**>(from_address), 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<size_t>(words_per_double * copy_size)); 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CopySmiToDoubleElements(FixedArrayBase* from_base, 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t from_start, 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArrayBase* to_base, uint32_t to_start, 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int raw_copy_size) { 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_allocation; 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int copy_size = raw_copy_size; 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (raw_copy_size < 0) { 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd || 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch copy_size = from_base->length() - from_start; 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = to_start + copy_size; i < to_base->length(); ++i) { 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray::cast(to_base)->set_the_hole(i); 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() && 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (copy_size + static_cast<int>(from_start)) <= from_base->length()); 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (copy_size == 0) return; 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* from = FixedArray::cast(from_base); 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray* to = FixedDoubleArray::cast(to_base); 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* the_hole = from->GetHeap()->the_hole_value(); 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size); 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch from_start < from_end; from_start++, to_start++) { 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* hole_or_smi = from->get(from_start); 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (hole_or_smi == the_hole) { 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to->set_the_hole(to_start); 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to->set(to_start, Smi::cast(hole_or_smi)->value()); 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CopyPackedSmiToDoubleElements(FixedArrayBase* from_base, 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t from_start, 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArrayBase* to_base, 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t to_start, int packed_size, 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int raw_copy_size) { 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_allocation; 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int copy_size = raw_copy_size; 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t to_end; 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (raw_copy_size < 0) { 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd || 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch copy_size = packed_size - from_start; 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to_end = to_base->length(); 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (uint32_t i = to_start + copy_size; i < to_end; ++i) { 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray::cast(to_base)->set_the_hole(i); 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to_end = to_start + static_cast<uint32_t>(copy_size); 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to_end = to_start + static_cast<uint32_t>(copy_size); 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(static_cast<int>(to_end) <= to_base->length()); 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(packed_size >= 0 && packed_size <= copy_size); 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() && 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (copy_size + static_cast<int>(from_start)) <= from_base->length()); 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (copy_size == 0) return; 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* from = FixedArray::cast(from_base); 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray* to = FixedDoubleArray::cast(to_base); 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size); 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch from_start < from_end; from_start++, to_start++) { 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* smi = from->get(from_start); 35613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!smi->IsTheHole(from->GetIsolate())); 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to->set(to_start, Smi::cast(smi)->value()); 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CopyObjectToDoubleElements(FixedArrayBase* from_base, 3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArrayBase* to_base, 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t to_start, int raw_copy_size) { 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_allocation; 3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size = raw_copy_size; 3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size < 0) { 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd || 3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch copy_size = from_base->length() - from_start; 3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = to_start + copy_size; i < to_base->length(); ++i) { 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray::cast(to_base)->set_the_hole(i); 3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() && 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (copy_size + static_cast<int>(from_start)) <= from_base->length()); 3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (copy_size == 0) return; 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArray* from = FixedArray::cast(from_base); 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray* to = FixedDoubleArray::cast(to_base); 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* the_hole = from->GetHeap()->the_hole_value(); 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (uint32_t from_end = from_start + copy_size; 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch from_start < from_end; from_start++, to_start++) { 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* hole_or_object = from->get(from_start); 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (hole_or_object == the_hole) { 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to->set_the_hole(to_start); 3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to->set(to_start, hole_or_object->Number()); 3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CopyDictionaryToDoubleElements(FixedArrayBase* from_base, 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedArrayBase* to_base, 3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_start, 4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int raw_copy_size) { 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_allocation; 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base); 4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size = raw_copy_size; 4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (copy_size < 0) { 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(copy_size == ElementsAccessor::kCopyToEnd || 4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size = from->max_number_key() + 1 - from_start; 4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = to_start + copy_size; i < to_base->length(); ++i) { 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray::cast(to_base)->set_the_hole(i); 4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (copy_size == 0) return; 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray* to = FixedDoubleArray::cast(to_base); 4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_length = to->length(); 4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (to_start + copy_size > to_length) { 4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size = to_length - to_start; 4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 42062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Isolate* isolate = from->GetIsolate(); 4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < copy_size; i++) { 42262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int entry = from->FindEntry(isolate, i + from_start); 4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry != SeededNumberDictionary::kNotFound) { 4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->set(i + to_start, from->ValueAt(entry)->Number()); 4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->set_the_hole(i + to_start); 4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void TraceTopFrame(Isolate* isolate) { 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StackFrameIterator it(isolate); 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (it.done()) { 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("unknown location (no JavaScript frames present)"); 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StackFrame* raw_frame = it.frame(); 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (raw_frame->is_internal()) { 439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Code* apply_builtin = 440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->builtins()->builtin(Builtins::kFunctionPrototypeApply); 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (raw_frame->unchecked_code() == apply_builtin) { 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("apply from "); 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch it.Advance(); 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch raw_frame = it.frame(); 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JavaScriptFrame::PrintTop(isolate, stdout, false, true); 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 45013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochstatic void SortIndices( 45113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<FixedArray> indices, uint32_t sort_size, 45213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch WriteBarrierMode write_barrier_mode = UPDATE_WRITE_BARRIER) { 45313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch struct { 45413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch bool operator()(Object* a, Object* b) { 45513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (a->IsSmi() || !a->IsUndefined(HeapObject::cast(a)->GetIsolate())) { 45613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!b->IsSmi() && b->IsUndefined(HeapObject::cast(b)->GetIsolate())) { 45713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return true; 45813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 45913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return a->Number() < b->Number(); 46013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 46113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return !b->IsSmi() && b->IsUndefined(HeapObject::cast(b)->GetIsolate()); 46213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 46313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } cmp; 46413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Object** start = 46513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch reinterpret_cast<Object**>(indices->GetFirstElementAddress()); 46613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch std::sort(start, start + sort_size, cmp); 46713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (write_barrier_mode != SKIP_WRITE_BARRIER) { 46813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(indices->GetIsolate()->heap(), *indices, 46913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 0, sort_size); 47013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 47113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 473f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstatic Maybe<bool> IncludesValueSlowPath(Isolate* isolate, 474f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> receiver, 475f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, 476f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t start_from, uint32_t length) { 477f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool search_for_hole = value->IsUndefined(isolate); 478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LookupIterator it(isolate, receiver, k); 480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!it.IsFound()) { 481f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (search_for_hole) return Just(true); 482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> element_k; 485f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k, 486f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object::GetProperty(&it), Nothing<bool>()); 487f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->SameValueZero(*element_k)) return Just(true); 489f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 492f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstatic Maybe<int64_t> IndexOfValueSlowPath(Isolate* isolate, 495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> receiver, 496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, 497f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t start_from, 498f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t length) { 499f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 500f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LookupIterator it(isolate, receiver, k); 501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!it.IsFound()) { 502f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 504f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> element_k; 505f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSIGN_RETURN_ON_EXCEPTION_VALUE( 506f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate, element_k, Object::GetProperty(&it), Nothing<int64_t>()); 507f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->StrictEquals(*element_k)) return Just<int64_t>(k); 509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(-1); 512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 51469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Base class for element handler implementations. Contains the 51569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// the common logic for objects with different ElementsKinds. 51669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Subclasses must specialize method for which the element 51769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// implementation differs from the base class implementation. 51869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 51969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// This class is intended to be used in the following way: 52069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 52169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// class SomeElementsAccessor : 52269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// public ElementsAccessorBase<SomeElementsAccessor, 52369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// BackingStoreClass> { 52469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// ... 52569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// } 52669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 52769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// This is an example of the Curiously Recurring Template Pattern (see 52869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use 52969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// CRTP to guarantee aggressive compile time optimizations (i.e. inlining and 53069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// specialization of SomeElementsAccessor methods). 531bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtemplate <typename Subclass, typename ElementsTraitsParam> 53269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ElementsAccessorBase : public ElementsAccessor { 533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit ElementsAccessorBase(const char* name) 5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ElementsAccessor(name) { } 5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef ElementsTraitsParam ElementsTraits; 5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef typename ElementsTraitsParam::BackingStore BackingStore; 5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static ElementsKind kind() { return ElementsTraits::Kind; } 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void ValidateContents(Handle<JSObject> holder, int length) { 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void ValidateImpl(Handle<JSObject> holder) { 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArrayBase> fixed_array_base(holder->elements()); 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!fixed_array_base->IsHeapObject()) return; 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Arrays that have been shifted in place can't be verified. 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (fixed_array_base->IsFiller()) return; 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int length = 0; 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (holder->IsJSArray()) { 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* length_obj = Handle<JSArray>::cast(holder)->length(); 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (length_obj->IsSmi()) { 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length = Smi::cast(length_obj)->value(); 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch length = fixed_array_base->length(); 5585d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 559bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::ValidateContents(holder, length); 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Validate(Handle<JSObject> holder) final { 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 564bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::ValidateImpl(holder); 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsPackedImpl(Handle<JSObject> holder, 568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> backing_store, uint32_t start, 569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t end) { 570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsFastPackedElementsKind(kind())) return true; 571c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Isolate* isolate = backing_store->GetIsolate(); 572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (uint32_t i = start; i < end; i++) { 573c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!Subclass::HasElementImpl(isolate, holder, i, backing_store, 574c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ALL_PROPERTIES)) { 575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return false; 576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return true; 5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void TryTransitionResultArrayToPacked(Handle<JSArray> array) { 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!IsHoleyElementsKind(kind())) return; 583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int length = Smi::cast(array->length())->value(); 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> backing_store(array->elements()); 585bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (!Subclass::IsPackedImpl(array, backing_store, 0, length)) { 586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind packed_kind = GetPackedElementsKind(kind()); 589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> new_map = 590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::GetElementsTransitionMap(array, packed_kind); 591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::MigrateToMap(array, new_map); 592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_trace_elements_transitions) { 593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::PrintElementsTransition(stdout, array, kind(), backing_store, 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch packed_kind, backing_store); 5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool HasElement(Handle<JSObject> holder, uint32_t index, 599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> backing_store, 600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyFilter filter) final { 601c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Subclass::HasElementImpl(holder->GetIsolate(), holder, index, 602c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch backing_store, filter); 6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 605c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static bool HasElementImpl(Isolate* isolate, Handle<JSObject> holder, 606c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t index, 607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> backing_store, 60862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PropertyFilter filter = ALL_PROPERTIES) { 609c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Subclass::GetEntryForIndexImpl(isolate, *holder, *backing_store, 610c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch index, filter) != kMaxUInt32; 6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 613109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bool HasAccessors(JSObject* holder) final { 614bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::HasAccessorsImpl(holder, holder->elements()); 6153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 617109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static bool HasAccessorsImpl(JSObject* holder, 618109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArrayBase* backing_store) { 619109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return false; 620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 622109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> Get(Handle<JSObject> holder, uint32_t entry) final { 62362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Subclass::GetInternalImpl(holder, entry); 624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 62662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static Handle<Object> GetInternalImpl(Handle<JSObject> holder, 62762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t entry) { 62862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Subclass::GetImpl(holder->GetIsolate(), holder->elements(), entry); 629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 63162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase* backing_store, 63262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t entry) { 633109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t index = GetIndexForEntryImpl(backing_store, entry); 634109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return handle(BackingStore::cast(backing_store)->get(index), isolate); 635109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 637109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch void Set(Handle<JSObject> holder, uint32_t entry, Object* value) final { 638bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::SetImpl(holder, entry, value); 639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Reconfigure(Handle<JSObject> object, Handle<FixedArrayBase> store, 642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t entry, Handle<Object> value, 643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAttributes attributes) final { 644bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::ReconfigureImpl(object, store, entry, value, attributes); 645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReconfigureImpl(Handle<JSObject> object, 648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> store, uint32_t entry, 649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> value, 650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAttributes attributes) { 651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Add(Handle<JSObject> object, uint32_t index, Handle<Object> value, 655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAttributes attributes, uint32_t new_capacity) final { 656bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::AddImpl(object, index, value, attributes, new_capacity); 657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void AddImpl(Handle<JSObject> object, uint32_t index, 660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> value, PropertyAttributes attributes, 661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t new_capacity) { 662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t Push(Handle<JSArray> receiver, Arguments* args, 6663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t push_size) final { 667bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::PushImpl(receiver, args, push_size); 668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static uint32_t PushImpl(Handle<JSArray> receiver, Arguments* args, 671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t push_sized) { 672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 0; 674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t Unshift(Handle<JSArray> receiver, Arguments* args, 677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t unshift_size) final { 678bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::UnshiftImpl(receiver, args, unshift_size); 679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static uint32_t UnshiftImpl(Handle<JSArray> receiver, Arguments* args, 682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t unshift_size) { 683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return 0; 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 6863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSArray> Slice(Handle<JSObject> receiver, uint32_t start, 688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t end) final { 689bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::SliceImpl(receiver, start, end); 690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, 693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t start, uint32_t end) { 694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Handle<JSArray>(); 696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 6983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSArray> Splice(Handle<JSArray> receiver, uint32_t start, 699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t delete_count, Arguments* args, 700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t add_count) final { 701bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::SpliceImpl(receiver, start, delete_count, args, add_count); 702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, 705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t start, uint32_t delete_count, 706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Arguments* args, uint32_t add_count) { 707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Handle<JSArray>(); 709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> Pop(Handle<JSArray> receiver) final { 712bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::PopImpl(receiver); 713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Handle<Object> PopImpl(Handle<JSArray> receiver) { 716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Handle<Object>(); 718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> Shift(Handle<JSArray> receiver) final { 721bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::ShiftImpl(receiver); 722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Handle<Object> ShiftImpl(Handle<JSArray> receiver) { 725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Handle<Object>(); 727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void SetLength(Handle<JSArray> array, uint32_t length) final { 730bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::SetLengthImpl(array->GetIsolate(), array, length, 731bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch handle(array->elements())); 732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, 735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length, 736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> backing_store) { 737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!array->SetLengthWouldNormalize(length)); 738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsFastElementsKind(array->GetElementsKind())); 739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t old_length = 0; 740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(array->length()->ToArrayIndex(&old_length)); 741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (old_length < length) { 743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind kind = array->GetElementsKind(); 744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!IsFastHoleyElementsKind(kind)) { 745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kind = GetHoleyElementsKind(kind); 746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::TransitionElementsKind(array, kind); 747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check whether the backing store should be shrunk. 751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t capacity = backing_store->length(); 752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch old_length = Min(old_length, capacity); 753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (length == 0) { 754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch array->initialize_elements(); 755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (length <= capacity) { 7563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (IsFastSmiOrObjectElementsKind(kind())) { 7573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch JSObject::EnsureWritableFastElements(array); 7583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (array->elements() != *backing_store) { 7593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch backing_store = handle(array->elements(), isolate); 7603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (2 * length <= capacity) { 763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If more than half the elements won't be used, trim the array. 76462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate->heap()->RightTrimFixedArray(*backing_store, capacity - length); 765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Otherwise, fill the unused tail with holes. 76762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BackingStore::cast(*backing_store)->FillWithHoles(length, old_length); 768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check whether the backing store should be expanded. 771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch capacity = Max(length, JSObject::NewElementsCapacity(capacity)); 772bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::GrowCapacityAndConvertImpl(array, capacity); 773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch array->set_length(Smi::FromInt(length)); 776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::ValidateElements(array); 7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 779c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t NumberOfElements(JSObject* receiver) final { 780c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Subclass::NumberOfElementsImpl(receiver, receiver->elements()); 781c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 782c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 783c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static uint32_t NumberOfElementsImpl(JSObject* receiver, 784c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FixedArrayBase* backing_store) { 785c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch UNREACHABLE(); 786c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 787c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 78813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { 7893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (receiver->IsJSArray()) { 7903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(JSArray::cast(receiver)->length()->IsSmi()); 7913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return static_cast<uint32_t>( 7923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Smi::cast(JSArray::cast(receiver)->length())->value()); 7933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 794bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::GetCapacityImpl(receiver, elements); 7953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 7963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 79713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static uint32_t GetMaxNumberOfEntries(JSObject* receiver, 79813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FixedArrayBase* elements) { 79913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Subclass::GetMaxIndex(receiver, elements); 80013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 80113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Handle<FixedArrayBase> ConvertElementsWithCapacity( 803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> object, Handle<FixedArrayBase> old_elements, 804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind from_kind, uint32_t capacity) { 805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ConvertElementsWithCapacity( 806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object, old_elements, from_kind, capacity, 0, 0, 807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsAccessor::kCopyToEndAndInitializeToHole); 808c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch } 809c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Handle<FixedArrayBase> ConvertElementsWithCapacity( 811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> object, Handle<FixedArrayBase> old_elements, 812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind from_kind, uint32_t capacity, int copy_size) { 813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ConvertElementsWithCapacity(object, old_elements, from_kind, 814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch capacity, 0, 0, copy_size); 815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 81669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Handle<FixedArrayBase> ConvertElementsWithCapacity( 818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> object, Handle<FixedArrayBase> old_elements, 819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind from_kind, uint32_t capacity, uint32_t src_index, 820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t dst_index, int copy_size) { 821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = object->GetIsolate(); 822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> new_elements; 823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsFastDoubleElementsKind(kind())) { 824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch new_elements = isolate->factory()->NewFixedDoubleArray(capacity); 825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch new_elements = isolate->factory()->NewUninitializedFixedArray(capacity); 827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int packed_size = kPackedSizeNotKnown; 830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsFastPackedElementsKind(from_kind) && object->IsJSArray()) { 831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch packed_size = Smi::cast(JSArray::cast(*object)->length())->value(); 832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 834bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::CopyElementsImpl(*old_elements, src_index, *new_elements, 835bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch from_kind, dst_index, packed_size, copy_size); 836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return new_elements; 838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 840f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static void TransitionElementsKindImpl(Handle<JSObject> object, 841f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Map> to_map) { 842f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Map> from_map = handle(object->map()); 843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ElementsKind from_kind = from_map->elements_kind(); 844f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ElementsKind to_kind = to_map->elements_kind(); 845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsFastHoleyElementsKind(from_kind)) { 846f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch to_kind = GetHoleyElementsKind(to_kind); 847f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 848f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (from_kind != to_kind) { 849f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // This method should never be called for any other case. 850f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(IsFastElementsKind(from_kind)); 851f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(IsFastElementsKind(to_kind)); 852f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_NE(TERMINAL_FAST_ELEMENTS_KIND, from_kind); 853f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 854f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<FixedArrayBase> from_elements(object->elements()); 855f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (object->elements() == object->GetHeap()->empty_fixed_array() || 856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch IsFastDoubleElementsKind(from_kind) == 857f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch IsFastDoubleElementsKind(to_kind)) { 858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // No change is needed to the elements() buffer, the transition 859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // only requires a map change. 860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch JSObject::MigrateToMap(object, to_map); 861f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 862f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK((IsFastSmiElementsKind(from_kind) && 863f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch IsFastDoubleElementsKind(to_kind)) || 864f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch (IsFastDoubleElementsKind(from_kind) && 865f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch IsFastObjectElementsKind(to_kind))); 866f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t capacity = static_cast<uint32_t>(object->elements()->length()); 867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<FixedArrayBase> elements = ConvertElementsWithCapacity( 868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch object, from_elements, from_kind, capacity); 869f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch JSObject::SetMapAndElements(object, to_map, elements); 870f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 871f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (FLAG_trace_elements_transitions) { 872f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch JSObject::PrintElementsTransition(stdout, object, from_kind, 873f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch from_elements, to_kind, 874f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch handle(object->elements())); 875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void GrowCapacityAndConvertImpl(Handle<JSObject> object, 880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t capacity) { 881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind from_kind = object->GetElementsKind(); 882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsFastSmiOrObjectElementsKind(from_kind)) { 883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Array optimizations rely on the prototype lookups of Array objects 884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // always returning undefined. If there is a store to the initial 885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // prototype object, make sure all of these optimizations are invalidated. 886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object->GetIsolate()->UpdateArrayProtectorOnSetLength(object); 887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> old_elements(object->elements()); 889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This method should only be called if there's a reason to update the 890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // elements. 891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsFastDoubleElementsKind(from_kind) != 892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFastDoubleElementsKind(kind()) || 893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsDictionaryElementsKind(from_kind) || 894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<uint32_t>(old_elements->length()) < capacity); 895bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::BasicGrowCapacityAndConvertImpl(object, old_elements, from_kind, 896bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch kind(), capacity); 897bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 898bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 899bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch static void BasicGrowCapacityAndConvertImpl( 900bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Handle<JSObject> object, Handle<FixedArrayBase> old_elements, 901bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ElementsKind from_kind, ElementsKind to_kind, uint32_t capacity) { 902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> elements = 903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConvertElementsWithCapacity(object, old_elements, from_kind, capacity); 904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsHoleyElementsKind(from_kind)) to_kind = GetHoleyElementsKind(to_kind); 906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, to_kind); 907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::SetMapAndElements(object, new_map, elements); 908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Transition through the allocation site as well if present. 910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::UpdateAllocationSite(object, to_kind); 911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FLAG_trace_elements_transitions) { 913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::PrintElementsTransition(stdout, object, from_kind, old_elements, 914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch to_kind, elements); 915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 918f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void TransitionElementsKind(Handle<JSObject> object, Handle<Map> map) final { 919f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Subclass::TransitionElementsKindImpl(object, map); 920f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 921f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void GrowCapacityAndConvert(Handle<JSObject> object, 923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t capacity) final { 924bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::GrowCapacityAndConvertImpl(object, capacity); 925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 927f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch bool GrowCapacity(Handle<JSObject> object, uint32_t index) final { 928f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // This function is intended to be called from optimized code. We don't 929f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // want to trigger lazy deopts there, so refuse to handle cases that would. 930f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (object->map()->is_prototype_map() || 931f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch object->WouldConvertToSlowElements(index)) { 932f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return false; 933f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 934f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<FixedArrayBase> old_elements(object->elements()); 935f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch uint32_t new_capacity = JSObject::NewElementsCapacity(index + 1); 936f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(static_cast<uint32_t>(old_elements->length()) < new_capacity); 937f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<FixedArrayBase> elements = 938f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ConvertElementsWithCapacity(object, old_elements, kind(), new_capacity); 939f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 940f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK_EQ(object->GetElementsKind(), kind()); 941f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Transition through the allocation site as well if present. 942f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kCheckOnly>( 943f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch object, kind())) { 944f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return false; 945f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 946f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 947f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch object->set_elements(*elements); 948f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return true; 949f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 950f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Delete(Handle<JSObject> obj, uint32_t entry) final { 952bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::DeleteImpl(obj, entry); 953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 955958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 956958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FixedArrayBase* to, ElementsKind from_kind, 957958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t to_start, int packed_size, 958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int copy_size) { 9593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 9603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void CopyElements(JSObject* from_holder, uint32_t from_start, 963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind from_kind, Handle<FixedArrayBase> to, 964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t to_start, int copy_size) final { 965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int packed_size = kPackedSizeNotKnown; 966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_packed = IsFastPackedElementsKind(from_kind) && 967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch from_holder->IsJSArray(); 968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_packed) { 969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch packed_size = 970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Smi::cast(JSArray::cast(from_holder)->length())->value(); 971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (copy_size >= 0 && packed_size > copy_size) { 972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch packed_size = copy_size; 973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 9743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FixedArrayBase* from = from_holder->elements(); 976bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // NOTE: the Subclass::CopyElementsImpl() methods 977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // violate the handlified function signature convention: 978958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // raw pointer parameters in the function that allocates. This is done 979958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // intentionally to avoid ArrayConcat() builtin performance degradation. 980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // 981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Details: The idea is that allocations actually happen only in case of 982958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // copying from object with fast double elements to object with object 983958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // elements. In all the other cases there are no allocations performed and 984958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // handle creation causes noticeable performance degradation of the builtin. 985bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::CopyElementsImpl(from, from_start, *to, from_kind, to_start, 986bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch packed_size, copy_size); 9873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 9883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 989c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void CopyElements(Handle<FixedArrayBase> source, ElementsKind source_kind, 990c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<FixedArrayBase> destination, int size) { 991c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Subclass::CopyElementsImpl(*source, 0, *destination, source_kind, 0, 992c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch kPackedSizeNotKnown, size); 993c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 994c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 9953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<SeededNumberDictionary> Normalize(Handle<JSObject> object) final { 996bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::NormalizeImpl(object, handle(object->elements())); 9973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 9983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 9993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Handle<SeededNumberDictionary> NormalizeImpl( 10003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSObject> object, Handle<FixedArrayBase> elements) { 10013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch UNREACHABLE(); 10023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Handle<SeededNumberDictionary>(); 10033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 10053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Maybe<bool> CollectValuesOrEntries(Isolate* isolate, Handle<JSObject> object, 10063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArray> values_or_entries, 10073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bool get_entries, int* nof_items, 10083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PropertyFilter filter) { 1009bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::CollectValuesOrEntriesImpl( 10103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch isolate, object, values_or_entries, get_entries, nof_items, filter); 10113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 10133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Maybe<bool> CollectValuesOrEntriesImpl( 10143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Isolate* isolate, Handle<JSObject> object, 10153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, 10163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PropertyFilter filter) { 10173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int count = 0; 101813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch KeyAccumulator accumulator(isolate, KeyCollectionMode::kOwnOnly, 101913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ALL_PROPERTIES); 1020bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::CollectElementIndicesImpl( 1021bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch object, handle(object->elements(), isolate), &accumulator); 10223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArray> keys = accumulator.GetKeys(); 10233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 10243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (int i = 0; i < keys->length(); ++i) { 10253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> key(keys->get(i), isolate); 10263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> value; 10273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t index; 10283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (!key->ToUint32(&index)) continue; 10293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1030bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch uint32_t entry = Subclass::GetEntryForIndexImpl( 1031c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate, *object, object->elements(), index, filter); 10323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (entry == kMaxUInt32) continue; 10333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1034bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch PropertyDetails details = Subclass::GetDetailsImpl(*object, entry); 10353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 10363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (details.kind() == kData) { 103762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = Subclass::GetImpl(isolate, object->elements(), entry); 10383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 10393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch LookupIterator it(isolate, object, index, LookupIterator::OWN); 10403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ASSIGN_RETURN_ON_EXCEPTION_VALUE( 10413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch isolate, value, Object::GetProperty(&it), Nothing<bool>()); 10423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (get_entries) { 10443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch value = MakeEntryPair(isolate, index, value); 10453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch values_or_entries->set(count++, *value); 10473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 10493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch *nof_items = count; 10503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Just(true); 10513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 10533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void CollectElementIndices(Handle<JSObject> object, 10543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> backing_store, 1055bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch KeyAccumulator* keys) final { 1056bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (keys->filter() & ONLY_ALL_CAN_READ) return; 1057bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::CollectElementIndicesImpl(object, backing_store, keys); 10583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void CollectElementIndicesImpl(Handle<JSObject> object, 1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> backing_store, 1062bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch KeyAccumulator* keys) { 1063109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_NE(DICTIONARY_ELEMENTS, kind()); 10643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Non-dictionary elements can't have all-can-read accessors. 106513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); 1066bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch PropertyFilter filter = keys->filter(); 1067c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Isolate* isolate = keys->isolate(); 1068c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Factory* factory = isolate->factory(); 1069bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch for (uint32_t i = 0; i < length; i++) { 1070c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (Subclass::HasElementImpl(isolate, object, i, backing_store, filter)) { 107113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch keys->AddKey(factory->NewNumberFromUint(i)); 1072109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 107569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 10763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Handle<FixedArray> DirectCollectElementIndicesImpl( 10773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Isolate* isolate, Handle<JSObject> object, 10783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> backing_store, GetKeysConversion convert, 10793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, 10803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t insertion_index = 0) { 108113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); 10823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (uint32_t i = 0; i < length; i++) { 1083c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (Subclass::HasElementImpl(isolate, object, i, backing_store, filter)) { 108413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (convert == GetKeysConversion::kConvertToString) { 10853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<String> index_string = isolate->factory()->Uint32ToString(i); 10863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch list->set(insertion_index, *index_string); 10873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 10883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); 10893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch insertion_index++; 10913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch *nof_indices = insertion_index; 10943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return list; 10953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 10963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1097f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MaybeHandle<FixedArray> PrependElementIndices( 1098f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> object, Handle<FixedArrayBase> backing_store, 1099f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<FixedArray> keys, GetKeysConversion convert, 1100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PropertyFilter filter) final { 1101bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::PrependElementIndicesImpl(object, backing_store, keys, 1102bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch convert, filter); 11033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 11043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static MaybeHandle<FixedArray> PrependElementIndicesImpl( 11063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSObject> object, Handle<FixedArrayBase> backing_store, 11073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArray> keys, GetKeysConversion convert, 11083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PropertyFilter filter) { 11093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Isolate* isolate = object->GetIsolate(); 11103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t nof_property_keys = keys->length(); 11113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t initial_list_length = 1112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Subclass::GetMaxNumberOfEntries(*object, *backing_store); 1113c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 11143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch initial_list_length += nof_property_keys; 1115f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (initial_list_length > FixedArray::kMaxLength || 1116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch initial_list_length < nof_property_keys) { 1117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return isolate->Throw<FixedArray>(isolate->factory()->NewRangeError( 1118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MessageTemplate::kInvalidArrayLength)); 1119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 11213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Collect the element indices into a new list. 1122c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch MaybeHandle<FixedArray> raw_array = 1123c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate->factory()->TryNewFixedArray(initial_list_length); 1124c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<FixedArray> combined_keys; 1125c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1126c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // If we have a holey backing store try to precisely estimate the backing 1127c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // store size as a last emergency measure if we cannot allocate the big 1128c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // array. 1129c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!raw_array.ToHandle(&combined_keys)) { 1130c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (IsHoleyElementsKind(kind())) { 1131c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // If we overestimate the result list size we might end up in the 1132c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // large-object space which doesn't free memory on shrinking the list. 1133c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Hence we try to estimate the final size for holey backing stores more 1134c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // precisely here. 1135c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch initial_list_length = 1136c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Subclass::NumberOfElementsImpl(*object, *backing_store); 1137c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch initial_list_length += nof_property_keys; 1138c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1139c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch combined_keys = isolate->factory()->NewFixedArray(initial_list_length); 1140c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1141c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 11423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t nof_indices = 0; 1143c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch bool needs_sorting = 1144c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind()); 1145bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch combined_keys = Subclass::DirectCollectElementIndicesImpl( 1146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate, object, backing_store, 1147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch needs_sorting ? GetKeysConversion::kKeepNumbers : convert, filter, 1148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch combined_keys, &nof_indices); 11493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (needs_sorting) { 1151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SortIndices(combined_keys, nof_indices); 11523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Indices from dictionary elements should only be converted after 11533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // sorting. 115413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (convert == GetKeysConversion::kConvertToString) { 11553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (uint32_t i = 0; i < nof_indices; i++) { 11563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> index_string = isolate->factory()->Uint32ToString( 1157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch combined_keys->get(i)->Number()); 11583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch combined_keys->set(i, *index_string); 11593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 11603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 11613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 11623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 11633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Copy over the passed-in property keys. 11643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CopyObjectToObjectElements(*keys, FAST_ELEMENTS, 0, *combined_keys, 11653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FAST_ELEMENTS, nof_indices, nof_property_keys); 11663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // For holey elements and arguments we might have to shrink the collected 1168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // keys since the estimates might be off. 1169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsHoleyElementsKind(kind()) || IsSloppyArgumentsElements(kind())) { 11703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Shrink combined_keys to the final size. 11713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int final_size = nof_indices + nof_property_keys; 11723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_LE(final_size, combined_keys->length()); 11733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch combined_keys->Shrink(final_size); 11743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 11753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 11763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return combined_keys; 11773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void AddElementsToKeyAccumulator(Handle<JSObject> receiver, 1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch KeyAccumulator* accumulator, 1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AddKeyConversion convert) final { 1182bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::AddElementsToKeyAccumulatorImpl(receiver, accumulator, convert); 1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 118469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static uint32_t GetCapacityImpl(JSObject* holder, 1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArrayBase* backing_store) { 1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return backing_store->length(); 1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 118969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { 1191bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::GetCapacityImpl(holder, backing_store); 1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 119369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Maybe<bool> IncludesValueImpl(Isolate* isolate, 1195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> receiver, 1196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, 1197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t start_from, uint32_t length) { 1198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return IncludesValueSlowPath(isolate, receiver, value, start_from, length); 1199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Maybe<bool> IncludesValue(Isolate* isolate, Handle<JSObject> receiver, 1202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, uint32_t start_from, 1203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t length) final { 1204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Subclass::IncludesValueImpl(isolate, receiver, value, start_from, 1205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length); 1206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, 1209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> receiver, 1210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, 1211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t start_from, uint32_t length) { 1212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return IndexOfValueSlowPath(isolate, receiver, value, start_from, length); 1213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Maybe<int64_t> IndexOfValue(Isolate* isolate, Handle<JSObject> receiver, 1216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, uint32_t start_from, 1217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t length) final { 1218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Subclass::IndexOfValueImpl(isolate, receiver, value, start_from, 1219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length); 1220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1221f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, 1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t entry) { 1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return entry; 1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1227c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, 1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArrayBase* backing_store, 1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t index, PropertyFilter filter) { 1230f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch uint32_t length = Subclass::GetMaxIndex(holder, backing_store); 1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsHoleyElementsKind(kind())) { 1232f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return index < length && 1233c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch !BackingStore::cast(backing_store) 1234c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ->is_the_hole(isolate, index) 1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? index 1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : kMaxUInt32; 1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return index < length ? index : kMaxUInt32; 123969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1242c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t GetEntryForIndex(Isolate* isolate, JSObject* holder, 1243c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FixedArrayBase* backing_store, 1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t index) final { 1245c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Subclass::GetEntryForIndexImpl(isolate, holder, backing_store, index, 1246bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ALL_PROPERTIES); 1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t entry) { 125162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return PropertyDetails(kData, NONE, 0, PropertyCellType::kNoCell); 1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1254109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { 125562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return PropertyDetails(kData, NONE, 0, PropertyCellType::kNoCell); 1256109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1257109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1258109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PropertyDetails GetDetails(JSObject* holder, uint32_t entry) final { 1259bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::GetDetailsImpl(holder, entry); 1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 126262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FixedArray> CreateListFromArray(Isolate* isolate, 126362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSArray> array) final { 126462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Subclass::CreateListFromArrayImpl(isolate, array); 126562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch }; 126662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 126762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static Handle<FixedArray> CreateListFromArrayImpl(Isolate* isolate, 126862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSArray> array) { 126962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 127062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Handle<FixedArray>(); 127162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 127262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass DictionaryElementsAccessor 1279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : public ElementsAccessorBase<DictionaryElementsAccessor, 1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKindTraits<DICTIONARY_ELEMENTS> > { 1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit DictionaryElementsAccessor(const char* name) 1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : ElementsAccessorBase<DictionaryElementsAccessor, 1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} 1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 128613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { 128713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // We cannot properly estimate this for dictionaries. 128813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch UNREACHABLE(); 128913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 129013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 129113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static uint32_t GetMaxNumberOfEntries(JSObject* receiver, 129213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FixedArrayBase* backing_store) { 1293c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return NumberOfElementsImpl(receiver, backing_store); 1294c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1295c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1296c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static uint32_t NumberOfElementsImpl(JSObject* receiver, 1297c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FixedArrayBase* backing_store) { 129813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); 129913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return dict->NumberOfElements(); 13003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 13013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, 1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length, 1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> backing_store) { 1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SeededNumberDictionary> dict = 1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SeededNumberDictionary>::cast(backing_store); 1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int capacity = dict->Capacity(); 1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t old_length = 0; 1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(array->length()->ToArrayLength(&old_length)); 1310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (length < old_length) { 1311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (dict->requires_slow_elements()) { 1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Find last non-deletable element in range of elements to be 1313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // deleted and adjust range accordingly. 1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int entry = 0; entry < capacity; entry++) { 1315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DisallowHeapAllocation no_gc; 1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* index = dict->KeyAt(entry); 1317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (index->IsNumber()) { 1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t number = static_cast<uint32_t>(index->Number()); 1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (length <= number && number < old_length) { 1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyDetails details = dict->DetailsAt(entry); 1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!details.IsConfigurable()) length = number + 1; 1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (length == 0) { 1328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Flush the backing store. 1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::ResetElements(array); 1330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DisallowHeapAllocation no_gc; 1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Remove elements that should be deleted. 1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int removed_entries = 0; 1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> the_hole_value = isolate->factory()->the_hole_value(); 1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int entry = 0; entry < capacity; entry++) { 1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* index = dict->KeyAt(entry); 1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (index->IsNumber()) { 1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t number = static_cast<uint32_t>(index->Number()); 1339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (length <= number && number < old_length) { 1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch dict->SetEntry(entry, the_hole_value, the_hole_value); 1341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch removed_entries++; 1342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 134469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Update the number of elements. 1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch dict->ElementsRemoved(removed_entries); 134869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 134969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length); 1352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch array->set_length(*length_obj); 135369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 135469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 1356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArrayBase* to, ElementsKind from_kind, 1357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t to_start, int packed_size, 1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int copy_size) { 1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 136069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 136169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { 1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(verwaest): Remove reliance on index in Shrink. 1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SeededNumberDictionary> dict( 1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SeededNumberDictionary::cast(obj->elements())); 1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t index = GetIndexForEntryImpl(*dict, entry); 1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, entry); 1369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(result); 137013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(result->IsTrue(dict->GetIsolate())); 1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArray> new_elements = 1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SeededNumberDictionary::Shrink(dict, index); 1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch obj->set_elements(*new_elements); 137469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 137569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1376109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static bool HasAccessorsImpl(JSObject* holder, 1377109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArrayBase* backing_store) { 13783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DisallowHeapAllocation no_gc; 1379109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); 1380109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!dict->requires_slow_elements()) return false; 1381109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int capacity = dict->Capacity(); 138213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Isolate* isolate = dict->GetIsolate(); 1383109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < capacity; i++) { 1384109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Object* key = dict->KeyAt(i); 138513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!dict->IsKey(isolate, key)) continue; 1386109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(!dict->IsDeleted(i)); 1387109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PropertyDetails details = dict->DetailsAt(i); 138862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (details.kind() == kAccessor) return true; 1389109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1390109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return false; 1391109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1392109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Object* GetRaw(FixedArrayBase* store, uint32_t entry) { 1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); 1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return backing_store->ValueAt(entry); 139669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 139769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 139862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase* backing_store, 139962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t entry) { 140062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return handle(GetRaw(backing_store, entry), isolate); 1401109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1402109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1403109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, 14048389745919cae02139ddc085a63c00d024269cf2Ben Murdoch Object* value) { 1405109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch SetImpl(holder->elements(), entry, value); 1406109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1407109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1408109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 1409109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Object* value) { 1410109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch SeededNumberDictionary::cast(backing_store)->ValueAtPut(entry, value); 1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReconfigureImpl(Handle<JSObject> object, 1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> store, uint32_t entry, 1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> value, 1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAttributes attributes) { 1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store); 1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (attributes != NONE) object->RequireSlowElements(dictionary); 1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch dictionary->ValueAtPut(entry, *value); 1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyDetails details = dictionary->DetailsAt(entry); 142162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch details = PropertyDetails(kData, attributes, details.dictionary_index(), 1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyCellType::kNoCell); 1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch dictionary->DetailsAtPut(entry, details); 1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void AddImpl(Handle<JSObject> object, uint32_t index, 1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> value, PropertyAttributes attributes, 1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t new_capacity) { 142962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PropertyDetails details(kData, attributes, 0, PropertyCellType::kNoCell); 1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SeededNumberDictionary> dictionary = 1431109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch object->HasFastElements() || object->HasFastStringWrapperElements() 1432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? JSObject::NormalizeElements(object) 1433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : handle(SeededNumberDictionary::cast(object->elements())); 1434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SeededNumberDictionary> new_dictionary = 143562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch SeededNumberDictionary::AddNumberEntry(dictionary, index, value, 143662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch details, object); 1437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (attributes != NONE) object->RequireSlowElements(*new_dictionary); 1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (dictionary.is_identical_to(new_dictionary)) return; 1439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object->set_elements(*new_dictionary); 1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1442c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static bool HasEntryImpl(Isolate* isolate, FixedArrayBase* store, 1443c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t entry) { 1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DisallowHeapAllocation no_gc; 1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* index = dict->KeyAt(entry); 1447c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return !index->IsTheHole(isolate); 1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { 1451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DisallowHeapAllocation no_gc; 1452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 1453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t result = 0; 1454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(dict->KeyAt(entry)->ToArrayIndex(&result)); 1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1458c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, 1459c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FixedArrayBase* store, uint32_t index, 1460c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch PropertyFilter filter) { 1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DisallowHeapAllocation no_gc; 1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); 1463c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int entry = dictionary->FindEntry(isolate, index); 1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32; 1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (filter != ALL_PROPERTIES) { 1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyDetails details = dictionary->DetailsAt(entry); 1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAttributes attr = details.attributes(); 1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((attr & filter) != 0) return kMaxUInt32; 1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return static_cast<uint32_t>(entry); 1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1473109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { 1474109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return GetDetailsImpl(holder->elements(), entry); 1475109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1476109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t entry) { 1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry); 1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 14823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static uint32_t FilterKey(Handle<SeededNumberDictionary> dictionary, 14833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int entry, Object* raw_key, PropertyFilter filter) { 14843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(!dictionary->IsDeleted(entry)); 14853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(raw_key->IsNumber()); 14863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_LE(raw_key->Number(), kMaxUInt32); 14873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PropertyDetails details = dictionary->DetailsAt(entry); 14883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PropertyAttributes attr = details.attributes(); 14893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if ((attr & filter) != 0) return kMaxUInt32; 14903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return static_cast<uint32_t>(raw_key->Number()); 14913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 14923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 149313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static uint32_t GetKeyForEntryImpl(Isolate* isolate, 149413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<SeededNumberDictionary> dictionary, 14953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int entry, PropertyFilter filter) { 14963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DisallowHeapAllocation no_gc; 14973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Object* raw_key = dictionary->KeyAt(entry); 149813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!dictionary->IsKey(isolate, raw_key)) return kMaxUInt32; 14993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return FilterKey(dictionary, entry, raw_key, filter); 15003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 15013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void CollectElementIndicesImpl(Handle<JSObject> object, 1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> backing_store, 1504bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch KeyAccumulator* keys) { 1505bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (keys->filter() & SKIP_STRINGS) return; 15063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Isolate* isolate = keys->isolate(); 1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SeededNumberDictionary> dictionary = 1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SeededNumberDictionary>::cast(backing_store); 1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int capacity = dictionary->Capacity(); 151013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<FixedArray> elements = isolate->factory()->NewFixedArray( 151113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch GetMaxNumberOfEntries(*object, *backing_store)); 151213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch int insertion_index = 0; 1513bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch PropertyFilter filter = keys->filter(); 1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < capacity; i++) { 1515f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* raw_key = dictionary->KeyAt(i); 1516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!dictionary->IsKey(isolate, raw_key)) continue; 1517f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t key = FilterKey(dictionary, i, raw_key, filter); 1518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (key == kMaxUInt32) { 1519f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch keys->AddShadowingKey(raw_key); 1520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 1521f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch elements->set(insertion_index, raw_key); 152313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch insertion_index++; 152413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 152513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SortIndices(elements, insertion_index); 152613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch for (int i = 0; i < insertion_index; i++) { 152713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch keys->AddKey(elements->get(i)); 1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1530109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 15313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Handle<FixedArray> DirectCollectElementIndicesImpl( 15323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Isolate* isolate, Handle<JSObject> object, 15333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> backing_store, GetKeysConversion convert, 15343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, 15353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t insertion_index = 0) { 15363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (filter & SKIP_STRINGS) return list; 15373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (filter & ONLY_ALL_CAN_READ) return list; 15383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 15393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<SeededNumberDictionary> dictionary = 15403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<SeededNumberDictionary>::cast(backing_store); 15413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t capacity = dictionary->Capacity(); 15423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (uint32_t i = 0; i < capacity; i++) { 154313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t key = GetKeyForEntryImpl(isolate, dictionary, i, filter); 15443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (key == kMaxUInt32) continue; 15453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> index = isolate->factory()->NewNumberFromUint(key); 15463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch list->set(insertion_index, *index); 15473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch insertion_index++; 15483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 15493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch *nof_indices = insertion_index; 15503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return list; 15513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 15523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1553109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 1554109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch KeyAccumulator* accumulator, 1555109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AddKeyConversion convert) { 15563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Isolate* isolate = accumulator->isolate(); 15573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> undefined = isolate->factory()->undefined_value(); 15583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> the_hole = isolate->factory()->the_hole_value(); 1559c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<SeededNumberDictionary> dictionary( 1560c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SeededNumberDictionary::cast(receiver->elements()), isolate); 1561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int capacity = dictionary->Capacity(); 1562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < capacity; i++) { 1563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Object* k = dictionary->KeyAt(i); 15643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (k == *undefined) continue; 15653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (k == *the_hole) continue; 1566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (dictionary->IsDeleted(i)) continue; 1567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Object* value = dictionary->ValueAt(i); 156813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!value->IsTheHole(isolate)); 1569109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(!value->IsAccessorPair()); 1570109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(!value->IsAccessorInfo()); 1571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch accumulator->AddKey(value, convert); 1572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static bool IncludesValueFastPath(Isolate* isolate, Handle<JSObject> receiver, 1576f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, uint32_t start_from, 1577f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t length, Maybe<bool>* result) { 1578f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DisallowHeapAllocation no_gc; 1579f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SeededNumberDictionary* dictionary = 1580f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SeededNumberDictionary::cast(receiver->elements()); 1581f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int capacity = dictionary->Capacity(); 1582f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* the_hole = isolate->heap()->the_hole_value(); 1583f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* undefined = isolate->heap()->undefined_value(); 1584f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1585f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Scan for accessor properties. If accessors are present, then elements 1586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // must be accessed in order via the slow path. 1587f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool found = false; 1588f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (int i = 0; i < capacity; ++i) { 1589f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* k = dictionary->KeyAt(i); 1590f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (k == the_hole) continue; 1591f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (k == undefined) continue; 1592f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1593f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t index; 1594f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!k->ToArrayIndex(&index) || index < start_from || index >= length) { 1595f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 1596f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1597f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 159862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (dictionary->DetailsAt(i).kind() == kAccessor) { 1599f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Restart from beginning in slow path, otherwise we may observably 1600f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // access getters out of order 1601f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return false; 1602f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (!found) { 1603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* element_k = dictionary->ValueAt(i); 1604f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->SameValueZero(element_k)) found = true; 1605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1606f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1607f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1608f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *result = Just(found); 1609f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return true; 1610f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1611f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1612f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Maybe<bool> IncludesValueImpl(Isolate* isolate, 1613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> receiver, 1614f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, 1615f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t start_from, uint32_t length) { 1616f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); 1617f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool search_for_hole = value->IsUndefined(isolate); 1618f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1619f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!search_for_hole) { 1620f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Maybe<bool> result = Nothing<bool>(); 1621f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (DictionaryElementsAccessor::IncludesValueFastPath( 1622f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate, receiver, value, start_from, length, &result)) { 1623f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return result; 1624f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1626f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1627f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<SeededNumberDictionary> dictionary( 1628f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SeededNumberDictionary::cast(receiver->elements()), isolate); 1629f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Iterate through entire range, as accessing elements out of order is 1630f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // observable 1631f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 163262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int entry = dictionary->FindEntry(isolate, k); 1633f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (entry == SeededNumberDictionary::kNotFound) { 1634f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (search_for_hole) return Just(true); 1635f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 1636f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1637f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1638f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PropertyDetails details = GetDetailsImpl(*dictionary, entry); 1639f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (details.kind()) { 1640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kData: { 1641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* element_k = dictionary->ValueAt(entry); 1642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->SameValueZero(element_k)) return Just(true); 1643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kAccessor: { 1646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LookupIterator it(isolate, receiver, k, 1647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LookupIterator::OWN_SKIP_INTERCEPTOR); 1648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(it.IsFound()); 1649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(it.state(), LookupIterator::ACCESSOR); 1650f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> element_k; 1651f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1652f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSIGN_RETURN_ON_EXCEPTION_VALUE( 1653f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate, element_k, JSObject::GetPropertyWithAccessor(&it), 1654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Nothing<bool>()); 1655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1656f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->SameValueZero(*element_k)) return Just(true); 1657f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1658f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Bailout to slow path if elements on prototype changed 1659f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!JSObject::PrototypeHasNoElements(isolate, *receiver)) { 1660f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return IncludesValueSlowPath(isolate, receiver, value, k + 1, 1661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length); 1662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1663f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1664f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Continue if elements unchanged 1665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (*dictionary == receiver->elements()) continue; 1666f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1667f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Otherwise, bailout or update elements 1668f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver->GetElementsKind() != DICTIONARY_ELEMENTS) { 1669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver->map()->GetInitialElements() == receiver->elements()) { 1670f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // If switched to initial elements, return true if searching for 1671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // undefined, and false otherwise. 1672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(search_for_hole); 1673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Otherwise, switch to slow path. 1675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return IncludesValueSlowPath(isolate, receiver, value, k + 1, 1676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length); 1677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch dictionary = handle( 1679f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SeededNumberDictionary::cast(receiver->elements()), isolate); 1680f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 1685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1686f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1687f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, 1688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> receiver, 1689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, 1690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t start_from, uint32_t length) { 1691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); 1692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<SeededNumberDictionary> dictionary( 1694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SeededNumberDictionary::cast(receiver->elements()), isolate); 1695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Iterate through entire range, as accessing elements out of order is 1696f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // observable. 1697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 169862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int entry = dictionary->FindEntry(isolate, k); 1699f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (entry == SeededNumberDictionary::kNotFound) { 1700f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 1701f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1702f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1703f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch PropertyDetails details = GetDetailsImpl(*dictionary, entry); 1704f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (details.kind()) { 1705f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kData: { 1706f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* element_k = dictionary->ValueAt(entry); 1707f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->StrictEquals(element_k)) { 1708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(k); 1709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kAccessor: { 1713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LookupIterator it(isolate, receiver, k, 1714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LookupIterator::OWN_SKIP_INTERCEPTOR); 1715f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(it.IsFound()); 1716f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(it.state(), LookupIterator::ACCESSOR); 1717f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> element_k; 1718f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1719f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSIGN_RETURN_ON_EXCEPTION_VALUE( 1720f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate, element_k, JSObject::GetPropertyWithAccessor(&it), 1721f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Nothing<int64_t>()); 1722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->StrictEquals(*element_k)) return Just<int64_t>(k); 1724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Bailout to slow path if elements on prototype changed. 1726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!JSObject::PrototypeHasNoElements(isolate, *receiver)) { 1727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return IndexOfValueSlowPath(isolate, receiver, value, k + 1, 1728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length); 1729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Continue if elements unchanged. 1732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (*dictionary == receiver->elements()) continue; 1733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 1734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Otherwise, bailout or update elements. 1735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver->GetElementsKind() != DICTIONARY_ELEMENTS) { 1736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Otherwise, switch to slow path. 1737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return IndexOfValueSlowPath(isolate, receiver, value, k + 1, 1738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length); 1739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch dictionary = handle( 1741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch SeededNumberDictionary::cast(receiver->elements()), isolate); 1742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 1743f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 1746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(-1); 1747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 174869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 174969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 175069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 17513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Super class for all fast element arrays. 1752bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtemplate <typename Subclass, typename KindTraits> 1753bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochclass FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { 17545d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 17553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit FastElementsAccessor(const char* name) 1756bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch : ElementsAccessorBase<Subclass, KindTraits>(name) {} 17573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef typename KindTraits::BackingStore BackingStore; 17593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 17603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Handle<SeededNumberDictionary> NormalizeImpl( 17613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSObject> object, Handle<FixedArrayBase> store) { 17623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Isolate* isolate = store->GetIsolate(); 1763bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ElementsKind kind = Subclass::kind(); 17643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 17653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Ensure that notifications fire if the array or object prototypes are 17663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // normalizing. 17673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (IsFastSmiOrObjectElementsKind(kind)) { 17683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch isolate->UpdateArrayProtectorOnNormalizeElements(object); 17693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 17703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 17713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int capacity = object->GetFastElementsUsage(); 17723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<SeededNumberDictionary> dictionary = 17733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch SeededNumberDictionary::New(isolate, capacity); 17743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 17753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PropertyDetails details = PropertyDetails::Empty(); 17763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int j = 0; 17773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (int i = 0; j < capacity; i++) { 17783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (IsHoleyElementsKind(kind)) { 1779c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (BackingStore::cast(*store)->is_the_hole(isolate, i)) continue; 17803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 178162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> value = Subclass::GetImpl(isolate, *store, i); 178262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch dictionary = SeededNumberDictionary::AddNumberEntry(dictionary, i, value, 178362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch details, object); 17843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j++; 17853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 17863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return dictionary; 17873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 17883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void DeleteAtEnd(Handle<JSObject> obj, 1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<BackingStore> backing_store, uint32_t entry) { 1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = static_cast<uint32_t>(backing_store->length()); 1792c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Isolate* isolate = obj->GetIsolate(); 1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (; entry > 0; entry--) { 1794c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!backing_store->is_the_hole(isolate, entry - 1)) break; 1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (entry == 0) { 1797c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FixedArray* empty = isolate->heap()->empty_fixed_array(); 1798bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Dynamically ask for the elements kind here since we manually redirect 1799bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // the operations for argument backing stores. 1800bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (obj->GetElementsKind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS) { 1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray::cast(obj->elements())->set(1, empty); 18023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch obj->set_elements(empty); 18043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 18063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 18073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 180862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate->heap()->RightTrimFixedArray(*backing_store, length - entry); 18093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 18103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void DeleteCommon(Handle<JSObject> obj, uint32_t entry, 1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> store) { 1813109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(obj->HasFastSmiOrObjectElements() || obj->HasFastDoubleElements() || 1814109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch obj->HasFastArgumentsElements() || 1815109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch obj->HasFastStringWrapperElements()); 1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store); 1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!obj->IsJSArray() && 1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch entry == static_cast<uint32_t>(store->length()) - 1) { 1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DeleteAtEnd(obj, backing_store, entry); 1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1823c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Isolate* isolate = obj->GetIsolate(); 182462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch backing_store->set_the_hole(isolate, entry); 1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(verwaest): Move this out of elements.cc. 1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If an old space backing store is larger than a certain size and 1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // has too few used values, normalize it. 1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // To avoid doing the check on every delete we require at least 1830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // one adjacent hole to the value being deleted. 1831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int kMinLengthForSparsenessCheck = 64; 1832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (backing_store->length() < kMinLengthForSparsenessCheck) return; 1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (backing_store->GetHeap()->InNewSpace(*backing_store)) return; 1834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = 0; 1835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (obj->IsJSArray()) { 1836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSArray::cast(*obj)->length()->ToArrayLength(&length); 1837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch length = static_cast<uint32_t>(store->length()); 1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1840c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if ((entry > 0 && backing_store->is_the_hole(isolate, entry - 1)) || 1841c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch (entry + 1 < length && 1842c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch backing_store->is_the_hole(isolate, entry + 1))) { 1843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!obj->IsJSArray()) { 1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t i; 1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (i = entry + 1; i < length; i++) { 1846c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!backing_store->is_the_hole(isolate, i)) break; 1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (i == length) { 1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DeleteAtEnd(obj, backing_store, entry); 1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int num_used = 0; 1854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < backing_store->length(); ++i) { 1855c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!backing_store->is_the_hole(isolate, i)) { 1856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ++num_used; 1857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Bail out if a number dictionary wouldn't be able to save at least 1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 75% space. 1859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (4 * SeededNumberDictionary::ComputeCapacity(num_used) * 1860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SeededNumberDictionary::kEntrySize > 1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch backing_store->length()) { 1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 186469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 186569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::NormalizeElements(obj); 186769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReconfigureImpl(Handle<JSObject> object, 1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> store, uint32_t entry, 1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> value, 1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAttributes attributes) { 1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SeededNumberDictionary> dictionary = 1875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::NormalizeElements(object); 1876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch entry = dictionary->FindEntry(entry); 1877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DictionaryElementsAccessor::ReconfigureImpl(object, dictionary, entry, 1878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value, attributes); 1879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void AddImpl(Handle<JSObject> object, uint32_t index, 1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> value, PropertyAttributes attributes, 1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t new_capacity) { 1884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(NONE, attributes); 1885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind from_kind = object->GetElementsKind(); 1886bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ElementsKind to_kind = Subclass::kind(); 1887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsDictionaryElementsKind(from_kind) || 1888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFastDoubleElementsKind(from_kind) != 1889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsFastDoubleElementsKind(to_kind) || 1890bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::GetCapacityImpl(*object, object->elements()) != 1891bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch new_capacity) { 1892bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::GrowCapacityAndConvertImpl(object, new_capacity); 1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1894109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (IsFastElementsKind(from_kind) && from_kind != to_kind) { 1895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::TransitionElementsKind(object, to_kind); 1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsFastSmiOrObjectElementsKind(from_kind)) { 1898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsFastSmiOrObjectElementsKind(to_kind)); 1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::EnsureWritableFastElements(object); 1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1902bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::SetImpl(object, index, *value); 1903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { 1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind kind = KindTraits::Kind; 1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsFastPackedElementsKind(kind)) { 1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); 1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { 1911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::EnsureWritableFastElements(obj); 1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DeleteCommon(obj, entry, handle(obj->elements())); 1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1916c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static bool HasEntryImpl(Isolate* isolate, FixedArrayBase* backing_store, 1917c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t entry) { 1918c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return !BackingStore::cast(backing_store)->is_the_hole(isolate, entry); 1919c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1920c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 1921c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static uint32_t NumberOfElementsImpl(JSObject* receiver, 1922c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FixedArrayBase* backing_store) { 1923c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t max_index = Subclass::GetMaxIndex(receiver, backing_store); 1924c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (IsFastPackedElementsKind(Subclass::kind())) return max_index; 1925c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Isolate* isolate = receiver->GetIsolate(); 1926c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t count = 0; 1927c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (uint32_t i = 0; i < max_index; i++) { 1928c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (Subclass::HasEntryImpl(isolate, backing_store, i)) count++; 1929c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 1930c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return count; 1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1933109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 1934109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch KeyAccumulator* accumulator, 1935109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AddKeyConversion convert) { 1936c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Isolate* isolate = accumulator->isolate(); 1937c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<FixedArrayBase> elements(receiver->elements(), isolate); 193813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t length = Subclass::GetMaxNumberOfEntries(*receiver, *elements); 1939109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (uint32_t i = 0; i < length; i++) { 1940109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (IsFastPackedElementsKind(KindTraits::Kind) || 1941c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch HasEntryImpl(isolate, *elements, i)) { 194262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch accumulator->AddKey(Subclass::GetImpl(isolate, *elements, i), convert); 1943109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1944109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1945109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1946109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void ValidateContents(Handle<JSObject> holder, int length) { 1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if DEBUG 1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = holder->GetIsolate(); 1950bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Heap* heap = isolate->heap(); 1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArrayBase> elements(holder->elements(), isolate); 1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map* map = elements->map(); 1954bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { 1955bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK_NE(map, heap->fixed_double_array_map()); 1956bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (IsFastDoubleElementsKind(KindTraits::Kind)) { 1957bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK_NE(map, heap->fixed_cow_array_map()); 1958bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (map == heap->fixed_array_map()) DCHECK_EQ(0, length); 1959bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 1960bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UNREACHABLE(); 1961bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 1962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (length == 0) return; // nothing to do! 1963bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#if ENABLE_SLOW_DCHECKS 1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); 1966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsFastSmiElementsKind(KindTraits::Kind)) { 1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < length; i++) { 1968109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(BackingStore::get(*backing_store, i, isolate)->IsSmi() || 1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (IsFastHoleyElementsKind(KindTraits::Kind) && 1970c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch backing_store->is_the_hole(isolate, i))); 1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1972bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (KindTraits::Kind == FAST_ELEMENTS || 1973bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch KindTraits::Kind == FAST_DOUBLE_ELEMENTS) { 1974bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch for (int i = 0; i < length; i++) { 1975c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK(!backing_store->is_the_hole(isolate, i)); 1976bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 1977bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 1978bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(IsFastHoleyElementsKind(KindTraits::Kind)); 1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1981bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#endif 1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Handle<Object> PopImpl(Handle<JSArray> receiver) { 1985bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::RemoveElement(receiver, AT_END); 1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Handle<Object> ShiftImpl(Handle<JSArray> receiver) { 1989bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::RemoveElement(receiver, AT_START); 1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static uint32_t PushImpl(Handle<JSArray> receiver, 1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Arguments* args, uint32_t push_size) { 19943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> backing_store(receiver->elements()); 1995bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::AddArguments(receiver, backing_store, args, push_size, 1996bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch AT_END); 1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static uint32_t UnshiftImpl(Handle<JSArray> receiver, 2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Arguments* args, uint32_t unshift_size) { 20013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> backing_store(receiver->elements()); 2002bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Subclass::AddArguments(receiver, backing_store, args, unshift_size, 2003bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch AT_START); 2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, 2007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t start, uint32_t end) { 2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = receiver->GetIsolate(); 20093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> backing_store(receiver->elements(), isolate); 20103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int result_len = end < start ? 0u : end - start; 2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSArray> result_array = isolate->factory()->NewJSArray( 2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch KindTraits::Kind, result_len, result_len); 2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DisallowHeapAllocation no_gc; 2014bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::CopyElementsImpl(*backing_store, start, result_array->elements(), 2015bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch KindTraits::Kind, 0, kPackedSizeNotKnown, 2016bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch result_len); 2017bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::TryTransitionResultArrayToPacked(result_array); 2018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result_array; 2019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, 2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t start, uint32_t delete_count, 2023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Arguments* args, uint32_t add_count) { 2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = receiver->GetIsolate(); 2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Heap* heap = isolate->heap(); 2026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = Smi::cast(receiver->length())->value(); 2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t new_length = length - delete_count + add_count; 2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 20293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ElementsKind kind = KindTraits::Kind; 20303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (new_length <= static_cast<uint32_t>(receiver->elements()->length()) && 20313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch IsFastSmiOrObjectElementsKind(kind)) { 20323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HandleScope scope(isolate); 20333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch JSObject::EnsureWritableFastElements(receiver); 20343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 20353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 20363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> backing_store(receiver->elements(), isolate); 20373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (new_length == 0) { 2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver->set_elements(heap->empty_fixed_array()); 2040c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch receiver->set_length(Smi::kZero); 2041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return isolate->factory()->NewJSArrayWithElements( 2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch backing_store, KindTraits::Kind, delete_count); 2043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Construct the result array which holds the deleted elements. 2046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSArray> deleted_elements = isolate->factory()->NewJSArray( 2047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch KindTraits::Kind, delete_count, delete_count); 2048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (delete_count > 0) { 2049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DisallowHeapAllocation no_gc; 2050bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::CopyElementsImpl(*backing_store, start, 2051bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch deleted_elements->elements(), KindTraits::Kind, 2052bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 0, kPackedSizeNotKnown, delete_count); 2053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Delete and move elements to make space for add_count new elements. 2056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (add_count < delete_count) { 2057bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::SpliceShrinkStep(isolate, receiver, backing_store, start, 2058bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch delete_count, add_count, length, new_length); 2059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (add_count > delete_count) { 2060bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch backing_store = 2061bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::SpliceGrowStep(isolate, receiver, backing_store, start, 2062bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch delete_count, add_count, length, new_length); 2063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Copy over the arguments. 2066bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::CopyArguments(args, backing_store, add_count, 3, start); 2067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver->set_length(Smi::FromInt(new_length)); 2069bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::TryTransitionResultArrayToPacked(deleted_elements); 2070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return deleted_elements; 2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 20733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Maybe<bool> CollectValuesOrEntriesImpl( 20743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Isolate* isolate, Handle<JSObject> object, 20753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, 20763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PropertyFilter filter) { 2077c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<BackingStore> elements(BackingStore::cast(object->elements()), 2078c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate); 20793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int count = 0; 2080c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t length = elements->length(); 20813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (uint32_t index = 0; index < length; ++index) { 2082c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!HasEntryImpl(isolate, *elements, index)) continue; 208362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> value = Subclass::GetImpl(isolate, *elements, index); 20843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (get_entries) { 20853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch value = MakeEntryPair(isolate, index, value); 20863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 20873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch values_or_entries->set(count++, *value); 20883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 20893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch *nof_items = count; 20903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Just(true); 20913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 20923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 20933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static void MoveElements(Isolate* isolate, Handle<JSArray> receiver, 20943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> backing_store, int dst_index, 20953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int src_index, int len, int hole_start, 20963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int hole_end) { 20973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Heap* heap = isolate->heap(); 20983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<BackingStore> dst_elms = Handle<BackingStore>::cast(backing_store); 20993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (heap->CanMoveObjectStart(*dst_elms) && dst_index == 0) { 21003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Update all the copies of this backing_store handle. 21013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch *dst_elms.location() = 21023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch BackingStore::cast(heap->LeftTrimFixedArray(*dst_elms, src_index)); 21033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch receiver->set_elements(*dst_elms); 21043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Adjust the hole offset as the array has been shrunk. 21053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch hole_end -= src_index; 21063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_LE(hole_start, backing_store->length()); 21073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_LE(hole_end, backing_store->length()); 21083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else if (len != 0) { 21093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (IsFastDoubleElementsKind(KindTraits::Kind)) { 21103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MemMove(dst_elms->data_start() + dst_index, 21113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch dst_elms->data_start() + src_index, len * kDoubleSize); 21123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 21133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DisallowHeapAllocation no_gc; 21143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch heap->MoveElements(FixedArray::cast(*dst_elms), dst_index, src_index, 21153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch len); 21163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 21173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 21183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (hole_start != hole_end) { 21193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch dst_elms->FillWithHoles(hole_start, hole_end); 21203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 21213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 21223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 2123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Maybe<bool> IncludesValueImpl(Isolate* isolate, 2124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> receiver, 2125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> search_value, 2126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t start_from, uint32_t length) { 2127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); 2128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DisallowHeapAllocation no_gc; 2129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FixedArrayBase* elements_base = receiver->elements(); 2130f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* the_hole = isolate->heap()->the_hole_value(); 2131f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* undefined = isolate->heap()->undefined_value(); 2132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* value = *search_value; 2133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Elements beyond the capacity of the backing store treated as undefined. 2135f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value == undefined && 2136f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static_cast<uint32_t>(elements_base->length()) < length) { 2137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(true); 2138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (start_from >= length) return Just(false); 2141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length = std::min(static_cast<uint32_t>(elements_base->length()), length); 2143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!value->IsNumber()) { 2145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value == undefined) { 2146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Only FAST_ELEMENTS, FAST_HOLEY_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, and 2147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // FAST_HOLEY_DOUBLE_ELEMENTS can have `undefined` as a value. 2148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!IsFastObjectElementsKind(Subclass::kind()) && 2149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch !IsFastHoleyElementsKind(Subclass::kind())) { 2150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 2151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Search for `undefined` or The Hole in FAST_ELEMENTS, 2154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // FAST_HOLEY_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS 2155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsFastSmiOrObjectElementsKind(Subclass::kind())) { 2156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto elements = FixedArray::cast(receiver->elements()); 2157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 2159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* element_k = elements->get(k); 2160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsFastHoleyElementsKind(Subclass::kind()) && 2162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch element_k == the_hole) { 2163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(true); 2164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsFastObjectElementsKind(Subclass::kind()) && 2166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch element_k == undefined) { 2167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(true); 2168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 2171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Seach for The Hole in FAST_HOLEY_DOUBLE_ELEMENTS 2173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(Subclass::kind(), FAST_HOLEY_DOUBLE_ELEMENTS); 2174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto elements = FixedDoubleArray::cast(receiver->elements()); 2175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 2177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsFastHoleyElementsKind(Subclass::kind()) && 2178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch elements->is_the_hole(k)) { 2179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(true); 2180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 2183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (!IsFastObjectElementsKind(Subclass::kind())) { 2185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Search for non-number, non-Undefined value, with either 2186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS or 2187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // FAST_HOLEY_DOUBLE_ELEMENTS. Guaranteed to return false, since these 2188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // elements kinds can only contain Number values or undefined. 2189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 2190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Search for non-number, non-Undefined value with either 2192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // FAST_ELEMENTS or FAST_HOLEY_ELEMENTS. 2193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(IsFastObjectElementsKind(Subclass::kind())); 2194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto elements = FixedArray::cast(receiver->elements()); 2195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 2197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* element_k = elements->get(k); 2198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsFastHoleyElementsKind(Subclass::kind()) && 2199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch element_k == the_hole) { 2200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 2201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->SameValueZero(element_k)) return Just(true); 2204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 2206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!value->IsNaN()) { 2209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch double search_value = value->Number(); 2210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsFastDoubleElementsKind(Subclass::kind())) { 2211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Search for non-NaN Number in FAST_DOUBLE_ELEMENTS or 2212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // FAST_HOLEY_DOUBLE_ELEMENTS --- Skip TheHole, and trust UCOMISD or 2213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // similar operation for result. 2214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto elements = FixedDoubleArray::cast(receiver->elements()); 2215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 2217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsFastHoleyElementsKind(Subclass::kind()) && 2218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch elements->is_the_hole(k)) { 2219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 2220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2221f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (elements->get_scalar(k) == search_value) return Just(true); 2222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 2224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Search for non-NaN Number in FAST_ELEMENTS, FAST_HOLEY_ELEMENTS, 2226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // FAST_SMI_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS --- Skip non-Numbers, 2227f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // and trust UCOMISD or similar operation for result 2228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto elements = FixedArray::cast(receiver->elements()); 2229f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 2231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* element_k = elements->get(k); 2232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (element_k->IsNumber() && element_k->Number() == search_value) { 2233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(true); 2234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 2237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Search for NaN --- NaN cannot be represented with Smi elements, so 2240f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // abort if ElementsKind is FAST_SMI_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS 2241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsFastSmiElementsKind(Subclass::kind())) return Just(false); 2242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsFastDoubleElementsKind(Subclass::kind())) { 2244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Search for NaN in FAST_DOUBLE_ELEMENTS or 2245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // FAST_HOLEY_DOUBLE_ELEMENTS --- Skip The Hole and trust 2246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // std::isnan(elementK) for result 2247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto elements = FixedDoubleArray::cast(receiver->elements()); 2248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 2250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsFastHoleyElementsKind(Subclass::kind()) && 2251f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch elements->is_the_hole(k)) { 2252f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 2253f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2254f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (std::isnan(elements->get_scalar(k))) return Just(true); 2255f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2256f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 2257f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2258f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Search for NaN in FAST_ELEMENTS, FAST_HOLEY_ELEMENTS, 2259f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // FAST_SMI_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS. Return true if 2260f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // elementK->IsHeapNumber() && std::isnan(elementK->Number()) 2261f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(IsFastSmiOrObjectElementsKind(Subclass::kind())); 2262f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch auto elements = FixedArray::cast(receiver->elements()); 2263f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2264f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 2265f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (elements->get(k)->IsNaN()) return Just(true); 2266f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2267f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 2268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2271f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 227362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static Handle<FixedArray> CreateListFromArrayImpl(Isolate* isolate, 227462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSArray> array) { 227562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t length = 0; 227662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch array->length()->ToArrayLength(&length); 227762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FixedArray> result = isolate->factory()->NewFixedArray(length); 227862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<FixedArrayBase> elements(array->elements(), isolate); 227962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (uint32_t i = 0; i < length; i++) { 228062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!Subclass::HasElementImpl(isolate, array, i, elements)) continue; 228162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> value; 228262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = Subclass::GetImpl(isolate, *elements, i); 228362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (value->IsName()) { 228462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch value = isolate->factory()->InternalizeName(Handle<Name>::cast(value)); 228562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 228662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch result->set(i, *value); 228762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 228862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return result; 228962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 229062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 2291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 2292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // SpliceShrinkStep might modify the backing_store. 2293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, 2294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> backing_store, 2295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t start, uint32_t delete_count, 2296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t add_count, uint32_t len, 2297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t new_length) { 2298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int move_left_count = len - delete_count - start; 2299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const int move_left_dst_index = start + add_count; 2300bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::MoveElements(isolate, receiver, backing_store, 2301bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch move_left_dst_index, start + delete_count, 2302bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch move_left_count, new_length, len); 2303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // SpliceGrowStep might modify the backing_store. 2306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Handle<FixedArrayBase> SpliceGrowStep( 2307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Handle<JSArray> receiver, 2308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> backing_store, uint32_t start, 2309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t delete_count, uint32_t add_count, uint32_t length, 2310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t new_length) { 2311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check we do not overflow the new_length. 2312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK((add_count - delete_count) <= (Smi::kMaxValue - length)); 2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if backing_store is big enough. 2314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (new_length <= static_cast<uint32_t>(backing_store->length())) { 2315bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::MoveElements(isolate, receiver, backing_store, 2316bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch start + add_count, start + delete_count, 2317bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch (length - delete_count - start), 0, 0); 2318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // MoveElements updates the backing_store in-place. 2319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return backing_store; 2320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // New backing storage is needed. 2322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int capacity = JSObject::NewElementsCapacity(new_length); 2323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Partially copy all elements up to start. 2324bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Handle<FixedArrayBase> new_elms = Subclass::ConvertElementsWithCapacity( 2325bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch receiver, backing_store, KindTraits::Kind, capacity, start); 2326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Copy the trailing elements after start + delete_count 2327bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::CopyElementsImpl(*backing_store, start + delete_count, *new_elms, 2328bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch KindTraits::Kind, start + add_count, 2329bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch kPackedSizeNotKnown, 2330bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ElementsAccessor::kCopyToEndAndInitializeToHole); 2331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver->set_elements(*new_elms); 2332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return new_elms; 2333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Handle<Object> RemoveElement(Handle<JSArray> receiver, 2336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Where remove_position) { 2337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = receiver->GetIsolate(); 23383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ElementsKind kind = KindTraits::Kind; 23393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (IsFastSmiOrObjectElementsKind(kind)) { 23403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch HandleScope scope(isolate); 23413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch JSObject::EnsureWritableFastElements(receiver); 23423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 23433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> backing_store(receiver->elements(), isolate); 2344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = 2345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<uint32_t>(Smi::cast(receiver->length())->value()); 2346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(length > 0); 2347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int new_length = length - 1; 2348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int remove_index = remove_position == AT_START ? 0 : new_length; 234962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> result = 235062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Subclass::GetImpl(isolate, *backing_store, remove_index); 2351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (remove_position == AT_START) { 2352bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::MoveElements(isolate, receiver, backing_store, 0, 1, new_length, 2353bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 0, 0); 2354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2355bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::SetLengthImpl(isolate, receiver, new_length, backing_store); 2356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 235713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (IsHoleyElementsKind(kind) && result->IsTheHole(isolate)) { 23583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return isolate->factory()->undefined_value(); 2359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 2361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static uint32_t AddArguments(Handle<JSArray> receiver, 2364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> backing_store, 2365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Arguments* args, uint32_t add_size, 2366bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Where add_position) { 2367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = Smi::cast(receiver->length())->value(); 23683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(0 < add_size); 2369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t elms_len = backing_store->length(); 2370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check we do not overflow the new_length. 2371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(add_size <= static_cast<uint32_t>(Smi::kMaxValue - length)); 2372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t new_length = length + add_size; 2373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (new_length > elms_len) { 2375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // New backing storage is needed. 2376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t capacity = JSObject::NewElementsCapacity(new_length); 2377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If we add arguments to the start we have to shift the existing objects. 2378bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch int copy_dst_index = add_position == AT_START ? add_size : 0; 2379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Copy over all objects to a new backing_store. 2380bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch backing_store = Subclass::ConvertElementsWithCapacity( 2381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver, backing_store, KindTraits::Kind, capacity, 0, 2382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch copy_dst_index, ElementsAccessor::kCopyToEndAndInitializeToHole); 2383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver->set_elements(*backing_store); 2384bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (add_position == AT_START) { 2385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the backing store has enough capacity and we add elements to the 2386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // start we have to shift the existing objects. 2387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate = receiver->GetIsolate(); 2388bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::MoveElements(isolate, receiver, backing_store, add_size, 0, 2389bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch length, 0, 0); 2390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2392bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch int insertion_index = add_position == AT_START ? 0 : length; 2393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Copy the arguments to the start. 2394bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::CopyArguments(args, backing_store, add_size, 1, insertion_index); 2395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Set the length. 2396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver->set_length(Smi::FromInt(new_length)); 2397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return new_length; 2398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void CopyArguments(Arguments* args, Handle<FixedArrayBase> dst_store, 2401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t copy_size, uint32_t src_index, 2402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t dst_index) { 2403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Add the provided values. 2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DisallowHeapAllocation no_gc; 2405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArrayBase* raw_backing_store = *dst_store; 2406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); 2407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (uint32_t i = 0; i < copy_size; i++) { 2408bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Object* argument = (*args)[src_index + i]; 240913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!argument->IsTheHole(raw_backing_store->GetIsolate())); 2410bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::SetImpl(raw_backing_store, dst_index + i, argument, mode); 2411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2415bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtemplate <typename Subclass, typename KindTraits> 2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FastSmiOrObjectElementsAccessor 2417bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch : public FastElementsAccessor<Subclass, KindTraits> { 2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit FastSmiOrObjectElementsAccessor(const char* name) 2420bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch : FastElementsAccessor<Subclass, KindTraits>(name) {} 2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2422109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, 2423109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Object* value) { 2424109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch SetImpl(holder->elements(), entry, value); 2425109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2426109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 2428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* value) { 2429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray::cast(backing_store)->set(entry, value); 2430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 2433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* value, WriteBarrierMode mode) { 2434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray::cast(backing_store)->set(entry, value, mode); 2435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { 2438bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch uint32_t index = Subclass::GetIndexForEntryImpl(backing_store, entry); 2439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return backing_store->get(index); 2440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // NOTE: this method violates the handlified function signature convention: 2443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // raw pointer parameters in the function that allocates. 2444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // See ElementsAccessor::CopyElements() for details. 2445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // This method could actually allocate if copying from double elements to 2446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // object elements. 2447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 2448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FixedArrayBase* to, ElementsKind from_kind, 2449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t to_start, int packed_size, 2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int copy_size) { 2451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DisallowHeapAllocation no_gc; 2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind to_kind = KindTraits::Kind; 2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (from_kind) { 2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_SMI_ELEMENTS: 2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_HOLEY_SMI_ELEMENTS: 2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_ELEMENTS: 2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_HOLEY_ELEMENTS: 2458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CopyObjectToObjectElements(from, from_kind, from_start, to, to_kind, 2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch to_start, copy_size); 2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 24613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_DOUBLE_ELEMENTS: 2462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case FAST_HOLEY_DOUBLE_ELEMENTS: { 2463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AllowHeapAllocation allow_allocation; 2464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsFastObjectElementsKind(to_kind)); 2465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CopyDoubleToObjectElements(from, from_start, to, to_start, copy_size); 2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case DICTIONARY_ELEMENTS: 2469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CopyDictionaryToObjectElements(from, from_start, to, to_kind, to_start, 2470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier copy_size); 2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FAST_SLOPPY_ARGUMENTS_ELEMENTS: 2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: 2474bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case FAST_STRING_WRAPPER_ELEMENTS: 2475bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case SLOW_STRING_WRAPPER_ELEMENTS: 2476109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS: 2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TYPED_ARRAYS(TYPED_ARRAY_CASE) 2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef TYPED_ARRAY_CASE 2479109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // This function is currently only used for JSArrays with non-zero 2480109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // length. 2481109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch UNREACHABLE(); 2482109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 2483109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case NO_ELEMENTS: 2484109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; // Nothing to do. 24853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 24863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2487f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, 2489f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> receiver, 2490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> search_value, 2491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t start_from, uint32_t length) { 2492f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); 2493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DisallowHeapAllocation no_gc; 2494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FixedArrayBase* elements_base = receiver->elements(); 2495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* value = *search_value; 2496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2497f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (start_from >= length) return Just<int64_t>(-1); 2498f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2499f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length = std::min(static_cast<uint32_t>(elements_base->length()), length); 2500f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Only FAST_{,HOLEY_}ELEMENTS can store non-numbers. 2502f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!value->IsNumber() && !IsFastObjectElementsKind(Subclass::kind())) { 2503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(-1); 2504f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2505f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // NaN can never be found by strict equality. 2506f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->IsNaN()) return Just<int64_t>(-1); 2507f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2508f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FixedArray* elements = FixedArray::cast(receiver->elements()); 2509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 2510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->StrictEquals(elements->get(k))) return Just<int64_t>(k); 2511f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(-1); 2513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 25153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 25163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FastPackedSmiElementsAccessor 2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : public FastSmiOrObjectElementsAccessor< 2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FastPackedSmiElementsAccessor, 2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKindTraits<FAST_SMI_ELEMENTS> > { 2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit FastPackedSmiElementsAccessor(const char* name) 2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : FastSmiOrObjectElementsAccessor< 2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FastPackedSmiElementsAccessor, 2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKindTraits<FAST_SMI_ELEMENTS> >(name) {} 2526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 2527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FastHoleySmiElementsAccessor 2530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : public FastSmiOrObjectElementsAccessor< 2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FastHoleySmiElementsAccessor, 2532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKindTraits<FAST_HOLEY_SMI_ELEMENTS> > { 2533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit FastHoleySmiElementsAccessor(const char* name) 2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : FastSmiOrObjectElementsAccessor< 2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FastHoleySmiElementsAccessor, 2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKindTraits<FAST_HOLEY_SMI_ELEMENTS> >(name) {} 253869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 253969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 254069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FastPackedObjectElementsAccessor 2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : public FastSmiOrObjectElementsAccessor< 2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FastPackedObjectElementsAccessor, 2544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKindTraits<FAST_ELEMENTS> > { 2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 2546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit FastPackedObjectElementsAccessor(const char* name) 2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : FastSmiOrObjectElementsAccessor< 2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FastPackedObjectElementsAccessor, 2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKindTraits<FAST_ELEMENTS> >(name) {} 2550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FastHoleyObjectElementsAccessor 2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : public FastSmiOrObjectElementsAccessor< 2555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FastHoleyObjectElementsAccessor, 2556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKindTraits<FAST_HOLEY_ELEMENTS> > { 2557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit FastHoleyObjectElementsAccessor(const char* name) 2559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : FastSmiOrObjectElementsAccessor< 2560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FastHoleyObjectElementsAccessor, 2561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKindTraits<FAST_HOLEY_ELEMENTS> >(name) {} 2562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 2563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2564bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtemplate <typename Subclass, typename KindTraits> 256569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass FastDoubleElementsAccessor 2566bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch : public FastElementsAccessor<Subclass, KindTraits> { 25673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 25683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit FastDoubleElementsAccessor(const char* name) 2569bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch : FastElementsAccessor<Subclass, KindTraits>(name) {} 25703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 257162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase* backing_store, 257262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t entry) { 2573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return FixedDoubleArray::get(FixedDoubleArray::cast(backing_store), entry, 2574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate); 2575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2577109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, 2578109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Object* value) { 2579109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch SetImpl(holder->elements(), entry, value); 2580109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2581109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 2583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* value) { 2584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); 2585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 2588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* value, WriteBarrierMode mode) { 2589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); 2590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2592958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 2593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FixedArrayBase* to, ElementsKind from_kind, 2594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t to_start, int packed_size, 2595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int copy_size) { 2596958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DisallowHeapAllocation no_allocation; 2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (from_kind) { 2598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_SMI_ELEMENTS: 2599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CopyPackedSmiToDoubleElements(from, from_start, to, to_start, 2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch packed_size, copy_size); 2601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_HOLEY_SMI_ELEMENTS: 2603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CopySmiToDoubleElements(from, from_start, to, to_start, copy_size); 2604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 26053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_DOUBLE_ELEMENTS: 2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_HOLEY_DOUBLE_ELEMENTS: 2607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CopyDoubleToDoubleElements(from, from_start, to, to_start, copy_size); 2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_ELEMENTS: 2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_HOLEY_ELEMENTS: 2611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size); 2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case DICTIONARY_ELEMENTS: 2614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CopyDictionaryToDoubleElements(from, from_start, to, to_start, 2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch copy_size); 2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 2617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case FAST_SLOPPY_ARGUMENTS_ELEMENTS: 2618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: 2619109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case FAST_STRING_WRAPPER_ELEMENTS: 2620109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case SLOW_STRING_WRAPPER_ELEMENTS: 2621109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch case NO_ELEMENTS: 2622109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS: 2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TYPED_ARRAYS(TYPED_ARRAY_CASE) 2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef TYPED_ARRAY_CASE 2625109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // This function is currently only used for JSArrays with non-zero 2626109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // length. 2627109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch UNREACHABLE(); 2628109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 262969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 263069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 2631f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2632f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, 2633f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> receiver, 2634f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> search_value, 2635f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t start_from, uint32_t length) { 2636f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); 2637f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DisallowHeapAllocation no_gc; 2638f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FixedArrayBase* elements_base = receiver->elements(); 2639f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* value = *search_value; 2640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length = std::min(static_cast<uint32_t>(elements_base->length()), length); 2642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 264362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (start_from >= length) return Just<int64_t>(-1); 264462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 2645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!value->IsNumber()) { 2646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(-1); 2647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->IsNaN()) { 2649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(-1); 2650f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2651f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch double numeric_search_value = value->Number(); 2652f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FixedDoubleArray* elements = FixedDoubleArray::cast(receiver->elements()); 2653f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 2655f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (elements->is_the_hole(k)) { 2656f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 2657f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2658f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (elements->get_scalar(k) == numeric_search_value) { 2659f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(k); 2660f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2661f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2662f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(-1); 2663f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 266569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 2666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FastPackedDoubleElementsAccessor 2668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : public FastDoubleElementsAccessor< 2669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FastPackedDoubleElementsAccessor, 2670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > { 2671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 2672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit FastPackedDoubleElementsAccessor(const char* name) 2673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : FastDoubleElementsAccessor< 2674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FastPackedDoubleElementsAccessor, 2675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >(name) {} 2676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 2677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FastHoleyDoubleElementsAccessor 2680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : public FastDoubleElementsAccessor< 2681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FastHoleyDoubleElementsAccessor, 2682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> > { 2683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 2684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit FastHoleyDoubleElementsAccessor(const char* name) 2685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : FastDoubleElementsAccessor< 2686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FastHoleyDoubleElementsAccessor, 2687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> >(name) {} 268869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 268969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 269069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 269169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Super class for all external element arrays. 2692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <ElementsKind Kind, typename ctype> 2693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass TypedElementsAccessor 2694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : public ElementsAccessorBase<TypedElementsAccessor<Kind, ctype>, 2695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ElementsKindTraits<Kind>> { 26963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 2697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit TypedElementsAccessor(const char* name) 2698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : ElementsAccessorBase<AccessorClass, 26993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<Kind> >(name) {} 27003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 2702f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch typedef TypedElementsAccessor<Kind, ctype> AccessorClass; 27033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2704109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, 2705109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Object* value) { 2706109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch SetImpl(holder->elements(), entry, value); 2707109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2708109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 2710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* value) { 2711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BackingStore::cast(backing_store)->SetValue(entry, value); 2712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2713592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* value, WriteBarrierMode mode) { 2716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BackingStore::cast(backing_store)->SetValue(entry, value); 2717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 271962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase* backing_store, 272062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t entry) { 2721109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return BackingStore::get(BackingStore::cast(backing_store), entry); 2722109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2723109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2724109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { 272562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return PropertyDetails(kData, DONT_DELETE, 0, PropertyCellType::kNoCell); 27263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 27273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 2729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t entry) { 273062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return PropertyDetails(kData, DONT_DELETE, 0, PropertyCellType::kNoCell); 2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2733c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static bool HasElementImpl(Isolate* isolate, Handle<JSObject> holder, 2734c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t index, 2735109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedArrayBase> backing_store, 2736109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PropertyFilter filter) { 2737109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return index < AccessorClass::GetCapacityImpl(*holder, *backing_store); 2738109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2739109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2740109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static bool HasAccessorsImpl(JSObject* holder, 2741109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArrayBase* backing_store) { 2742109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return false; 2743109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2744109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, 2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length, 2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> backing_store) { 27483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // External arrays do not support changing their length. 27493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 275069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 275169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { 2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 275469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 27553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, 2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t entry) { 2758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return entry; 27593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 276069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 2761c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, 2762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArrayBase* backing_store, 2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t index, PropertyFilter filter) { 2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return index < AccessorClass::GetCapacityImpl(holder, backing_store) 2765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? index 2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : kMaxUInt32; 2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 276869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 276962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static bool WasNeutered(JSObject* holder) { 277062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch JSArrayBufferView* view = JSArrayBufferView::cast(holder); 277162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return view->WasNeutered(); 277262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 277362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 2774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static uint32_t GetCapacityImpl(JSObject* holder, 2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArrayBase* backing_store) { 277662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (WasNeutered(holder)) return 0; 2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return backing_store->length(); 2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2779109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2780c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static uint32_t NumberOfElementsImpl(JSObject* receiver, 2781c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FixedArrayBase* backing_store) { 2782c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return AccessorClass::GetCapacityImpl(receiver, backing_store); 2783c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 2784c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 2785109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 2786109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch KeyAccumulator* accumulator, 2787109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AddKeyConversion convert) { 278862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Isolate* isolate = receiver->GetIsolate(); 27893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> elements(receiver->elements()); 2790109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t length = AccessorClass::GetCapacityImpl(*receiver, *elements); 2791109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (uint32_t i = 0; i < length; i++) { 279262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> value = AccessorClass::GetImpl(isolate, *elements, i); 2793109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch accumulator->AddKey(value, convert); 2794109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2795109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 27963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 27973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Maybe<bool> CollectValuesOrEntriesImpl( 27983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Isolate* isolate, Handle<JSObject> object, 27993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, 28003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PropertyFilter filter) { 28013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int count = 0; 28023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if ((filter & ONLY_CONFIGURABLE) == 0) { 28033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> elements(object->elements()); 28043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t length = AccessorClass::GetCapacityImpl(*object, *elements); 28053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (uint32_t index = 0; index < length; ++index) { 280662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> value = 280762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch AccessorClass::GetImpl(isolate, *elements, index); 28083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (get_entries) { 28093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch value = MakeEntryPair(isolate, index, value); 28103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 28113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch values_or_entries->set(count++, *value); 28123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 28133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 28143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch *nof_items = count; 28153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return Just(true); 28163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 281769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 2818f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Maybe<bool> IncludesValueImpl(Isolate* isolate, 2819f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> receiver, 2820f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, 2821f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t start_from, uint32_t length) { 2822f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); 2823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DisallowHeapAllocation no_gc; 282469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 282562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(caitp): return Just(false) here when implementing strict throwing on 282662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // neutered views. 282762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (WasNeutered(*receiver)) { 282862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Just(value->IsUndefined(isolate) && length > start_from); 282962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 283062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 2831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BackingStore* elements = BackingStore::cast(receiver->elements()); 2832f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->IsUndefined(isolate) && 2833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length > static_cast<uint32_t>(elements->length())) { 2834f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(true); 2835f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!value->IsNumber()) return Just(false); 283769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 2838f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch double search_value = value->Number(); 2839f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2840f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!std::isfinite(search_value)) { 2841f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Integral types cannot represent +Inf or NaN 2842f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (AccessorClass::kind() < FLOAT32_ELEMENTS || 2843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AccessorClass::kind() > FLOAT64_ELEMENTS) { 2844f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 2845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2846f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (search_value < std::numeric_limits<ctype>::lowest() || 2847f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch search_value > std::numeric_limits<ctype>::max()) { 2848f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Return false if value can't be represented in this space 2849f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 2850f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2851f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2852f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Prototype has no elements, and not searching for the hole --- limit 2853f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // search to backing store length. 2854f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (static_cast<uint32_t>(elements->length()) < length) { 2855f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length = elements->length(); 2856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2857f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!std::isnan(search_value)) { 2859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 2860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch double element_k = elements->get_scalar(k); 2861f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (element_k == search_value) return Just(true); 2862f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2863f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 2864f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2865f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 2866f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch double element_k = elements->get_scalar(k); 2867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (std::isnan(element_k)) return Just(true); 2868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2869f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 2870f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2871f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2872f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2873f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, 2874f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> receiver, 2875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, 2876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t start_from, uint32_t length) { 2877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); 2878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DisallowHeapAllocation no_gc; 2879f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 288062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (WasNeutered(*receiver)) return Just<int64_t>(-1); 288162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 2882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BackingStore* elements = BackingStore::cast(receiver->elements()); 2883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!value->IsNumber()) return Just<int64_t>(-1); 2884f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2885f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch double search_value = value->Number(); 2886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!std::isfinite(search_value)) { 2888f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Integral types cannot represent +Inf or NaN. 2889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (AccessorClass::kind() < FLOAT32_ELEMENTS || 2890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch AccessorClass::kind() > FLOAT64_ELEMENTS) { 2891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(-1); 2892f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2893f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (search_value < std::numeric_limits<ctype>::lowest() || 2894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch search_value > std::numeric_limits<ctype>::max()) { 2895f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Return false if value can't be represented in this ElementsKind. 2896f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(-1); 2897f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2898f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2899f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Prototype has no elements, and not searching for the hole --- limit 2900f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // search to backing store length. 2901f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (static_cast<uint32_t>(elements->length()) < length) { 2902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch length = elements->length(); 2903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2904f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (std::isnan(search_value)) { 2906f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(-1); 2907f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ctype typed_search_value = static_cast<ctype>(search_value); 2910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (static_cast<double>(typed_search_value) != search_value) { 2911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(-1); // Loss of precision. 2912f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2913f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2914f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 2915f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ctype element_k = elements->get_scalar(k); 2916f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (element_k == typed_search_value) return Just<int64_t>(k); 2917f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2918f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(-1); 2919f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2920f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}; 2921f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2922f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ 2923f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \ 2924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Fixed##Type##ElementsAccessor; 292569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 2926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) 2927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef FIXED_ELEMENTS_ACCESSOR 292869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 2929bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtemplate <typename Subclass, typename ArgumentsAccessor, typename KindTraits> 2930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SloppyArgumentsElementsAccessor 2931bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch : public ElementsAccessorBase<Subclass, KindTraits> { 293269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch public: 2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit SloppyArgumentsElementsAccessor(const char* name) 2934bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch : ElementsAccessorBase<Subclass, KindTraits>(name) { 2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(KindTraits::Kind); 2936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 29373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 293862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase* parameters, 293962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t entry) { 2940109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedArray> parameter_map(FixedArray::cast(parameters), isolate); 2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = parameter_map->length() - 2; 2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (entry < length) { 2943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* probe = parameter_map->get(entry + 2); 2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Context* context = Context::cast(parameter_map->get(0)); 2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int context_entry = Smi::cast(probe)->value(); 294713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!context->get(context_entry)->IsTheHole(isolate)); 2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return handle(context->get(context_entry), isolate); 2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Object is not mapped, defer to the arguments. 2951109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> result = ArgumentsAccessor::GetImpl( 295262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate, FixedArray::cast(parameter_map->get(1)), entry - length); 2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Elements of the arguments object in slow mode might be slow aliases. 2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (result->IsAliasedArgumentsEntry()) { 2955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DisallowHeapAllocation no_gc; 2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AliasedArgumentsEntry* alias = AliasedArgumentsEntry::cast(*result); 2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Context* context = Context::cast(parameter_map->get(0)); 2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int context_entry = alias->aliased_context_slot(); 295913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!context->get(context_entry)->IsTheHole(isolate)); 2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return handle(context->get(context_entry), isolate); 29613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 29633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 29643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 29653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2966f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static void TransitionElementsKindImpl(Handle<JSObject> object, 2967f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Map> map) { 2968f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 2969f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2970f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void GrowCapacityAndConvertImpl(Handle<JSObject> object, 2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t capacity) { 2973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2976109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, 2977109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Object* value) { 2978109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch SetImpl(holder->elements(), entry, value); 2979109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 2980109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 2981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static inline void SetImpl(FixedArrayBase* store, uint32_t entry, 2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* value) { 2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray* parameter_map = FixedArray::cast(store); 2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = parameter_map->length() - 2; 2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (entry < length) { 2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* probe = parameter_map->get(entry + 2); 2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Context* context = Context::cast(parameter_map->get(0)); 2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int context_entry = Smi::cast(probe)->value(); 298913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!context->get(context_entry)->IsTheHole(store->GetIsolate())); 2990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch context->set(context_entry, value); 2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 2993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* current = ArgumentsAccessor::GetRaw(arguments, entry - length); 2994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (current->IsAliasedArgumentsEntry()) { 2995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AliasedArgumentsEntry* alias = AliasedArgumentsEntry::cast(current); 2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Context* context = Context::cast(parameter_map->get(0)); 2997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int context_entry = alias->aliased_context_slot(); 299813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!context->get(context_entry)->IsTheHole(store->GetIsolate())); 2999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch context->set(context_entry, value); 3000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArgumentsAccessor::SetImpl(arguments, entry - length, value); 300269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 300369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 300469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 300569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, 3007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length, 3008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> parameter_map) { 3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Sloppy arguments objects are not arrays. 3010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 30113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 30123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static uint32_t GetCapacityImpl(JSObject* holder, 3014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArrayBase* backing_store) { 3015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray* parameter_map = FixedArray::cast(backing_store); 3016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return parameter_map->length() - 2 + 3018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ArgumentsAccessor::GetCapacityImpl(holder, arguments); 3019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 30203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3021f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static uint32_t GetMaxNumberOfEntries(JSObject* holder, 3022f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FixedArrayBase* backing_store) { 3023f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FixedArray* parameter_map = FixedArray::cast(backing_store); 3024f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 3025f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return parameter_map->length() - 2 + 3026f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ArgumentsAccessor::GetMaxNumberOfEntries(holder, arguments); 3027f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 3028f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3029c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static uint32_t NumberOfElementsImpl(JSObject* receiver, 3030c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FixedArrayBase* backing_store) { 3031c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FixedArray* parameter_map = FixedArray::cast(backing_store); 3032c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 3033c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t nof_elements = 0; 3034c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t length = parameter_map->length() - 2; 3035c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (uint32_t entry = 0; entry < length; entry++) { 3036c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (HasParameterMapArg(parameter_map, entry)) nof_elements++; 3037c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 3038c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return nof_elements + 3039c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ArgumentsAccessor::NumberOfElementsImpl(receiver, arguments); 3040c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 3041c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 3042109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 3043109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch KeyAccumulator* accumulator, 3044109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AddKeyConversion convert) { 3045c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Isolate* isolate = accumulator->isolate(); 3046c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<FixedArrayBase> elements(receiver->elements(), isolate); 3047c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t length = GetCapacityImpl(*receiver, *elements); 3048109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (uint32_t entry = 0; entry < length; entry++) { 3049c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!HasEntryImpl(isolate, *elements, entry)) continue; 305062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> value = GetImpl(isolate, *elements, entry); 3051109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch accumulator->AddKey(value, convert); 3052109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3053109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3054109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3055c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static bool HasEntryImpl(Isolate* isolate, FixedArrayBase* parameters, 3056c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t entry) { 3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray* parameter_map = FixedArray::cast(parameters); 3058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = parameter_map->length() - 2; 3059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (entry < length) { 3060f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return HasParameterMapArg(parameter_map, entry); 3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 306269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 3064c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return ArgumentsAccessor::HasEntryImpl(isolate, arguments, entry - length); 306569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 306669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3067109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static bool HasAccessorsImpl(JSObject* holder, 3068109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArrayBase* backing_store) { 3069109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArray* parameter_map = FixedArray::cast(backing_store); 3070109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 3071109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return ArgumentsAccessor::HasAccessorsImpl(holder, arguments); 3072109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3073109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static uint32_t GetIndexForEntryImpl(FixedArrayBase* parameters, 3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t entry) { 3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray* parameter_map = FixedArray::cast(parameters); 3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = parameter_map->length() - 2; 3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (entry < length) return entry; 3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); 308269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 308369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3084c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, 3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArrayBase* parameters, 3086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t index, PropertyFilter filter) { 3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray* parameter_map = FixedArray::cast(parameters); 3088f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (HasParameterMapArg(parameter_map, index)) return index; 3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 3091c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl( 3092c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate, holder, arguments, index, filter); 3093bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (entry == kMaxUInt32) return kMaxUInt32; 3094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return (parameter_map->length() - 2) + entry; 3095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3097109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { 3098109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArray* parameter_map = FixedArray::cast(holder->elements()); 3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = parameter_map->length() - 2; 3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (entry < length) { 310162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return PropertyDetails(kData, NONE, 0, PropertyCellType::kNoCell); 3102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 3104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ArgumentsAccessor::GetDetailsImpl(arguments, entry - length); 3105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3107f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch static bool HasParameterMapArg(FixedArray* parameter_map, uint32_t index) { 3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = parameter_map->length() - 2; 3109f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (index >= length) return false; 3110f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return !parameter_map->get(index + 2)->IsTheHole( 3111f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch parameter_map->GetIsolate()); 31123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 31133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { 3115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray* parameter_map = FixedArray::cast(obj->elements()); 3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = static_cast<uint32_t>(parameter_map->length()) - 2; 3117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (entry < length) { 3118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(kmillikin): We could check if this was the last aliased 3119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // parameter, and revert to normal elements in that case. That 3120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // would enable GC of the context. 3121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameter_map->set_the_hole(entry + 2); 3122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3123bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::DeleteFromArguments(obj, entry - length); 3124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 312569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 31263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 31273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static void CollectElementIndicesImpl(Handle<JSObject> object, 31283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> backing_store, 3129bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch KeyAccumulator* keys) { 313013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Isolate* isolate = keys->isolate(); 313113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch uint32_t nof_indices = 0; 313213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<FixedArray> indices = isolate->factory()->NewFixedArray( 313313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch GetCapacityImpl(*object, *backing_store)); 313413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DirectCollectElementIndicesImpl(isolate, object, backing_store, 313513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch GetKeysConversion::kKeepNumbers, 313613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ENUMERABLE_STRINGS, indices, &nof_indices); 313713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SortIndices(indices, nof_indices); 313813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch for (uint32_t i = 0; i < nof_indices; i++) { 313913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch keys->AddKey(indices->get(i)); 31403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 31413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 31423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 31433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Handle<FixedArray> DirectCollectElementIndicesImpl( 31443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Isolate* isolate, Handle<JSObject> object, 31453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> backing_store, GetKeysConversion convert, 31463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, 31473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t insertion_index = 0) { 3148f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<FixedArray> parameter_map(FixedArray::cast(*backing_store), isolate); 31493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t length = parameter_map->length() - 2; 31503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 31513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (uint32_t i = 0; i < length; ++i) { 315213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (parameter_map->get(i + 2)->IsTheHole(isolate)) continue; 315313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (convert == GetKeysConversion::kConvertToString) { 31543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<String> index_string = isolate->factory()->Uint32ToString(i); 31553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch list->set(insertion_index, *index_string); 31563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 31573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); 31583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 31593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch insertion_index++; 31603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 31613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 31623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1))); 31633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return ArgumentsAccessor::DirectCollectElementIndicesImpl( 31643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch isolate, object, store, convert, filter, list, nof_indices, 31653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch insertion_index); 31663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 3167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Maybe<bool> IncludesValueImpl(Isolate* isolate, 3169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> object, 3170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, 3171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t start_from, uint32_t length) { 3172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(JSObject::PrototypeHasNoElements(isolate, *object)); 3173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Map> original_map = handle(object->map(), isolate); 3174f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()), 3175f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch isolate); 3176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool search_for_hole = value->IsUndefined(isolate); 3177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 3179c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t entry = GetEntryForIndexImpl(isolate, *object, *parameter_map, k, 3180c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ALL_PROPERTIES); 3181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (entry == kMaxUInt32) { 3182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (search_for_hole) return Just(true); 3183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 3184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 3185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 318662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> element_k = 318762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Subclass::GetImpl(isolate, *parameter_map, entry); 3188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (element_k->IsAccessorPair()) { 3190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LookupIterator it(isolate, object, k, LookupIterator::OWN); 3191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(it.IsFound()); 3192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(it.state(), LookupIterator::ACCESSOR); 3193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k, 3194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object::GetPropertyWithAccessor(&it), 3195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Nothing<bool>()); 3196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->SameValueZero(*element_k)) return Just(true); 3198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (object->map() != *original_map) { 3200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Some mutation occurred in accessor. Abort "fast" path 3201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return IncludesValueSlowPath(isolate, object, value, k + 1, length); 3202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 3203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (value->SameValueZero(*element_k)) { 3204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(true); 3205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 3206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 3207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just(false); 3208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 3209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, 3211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSObject> object, 3212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, 3213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch uint32_t start_from, uint32_t length) { 3214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(JSObject::PrototypeHasNoElements(isolate, *object)); 3215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Map> original_map = handle(object->map(), isolate); 3216f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()), 3217f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch isolate); 3218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (uint32_t k = start_from; k < length; ++k) { 3220c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t entry = GetEntryForIndexImpl(isolate, *object, *parameter_map, k, 3221c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ALL_PROPERTIES); 3222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (entry == kMaxUInt32) { 3223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch continue; 3224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 3225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 322662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Object> element_k = 322762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Subclass::GetImpl(isolate, *parameter_map, entry); 3228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3229f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (element_k->IsAccessorPair()) { 3230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LookupIterator it(isolate, object, k, LookupIterator::OWN); 3231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(it.IsFound()); 3232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(it.state(), LookupIterator::ACCESSOR); 3233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k, 3234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object::GetPropertyWithAccessor(&it), 3235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Nothing<int64_t>()); 3236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (value->StrictEquals(*element_k)) { 3238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(k); 3239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 3240f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (object->map() != *original_map) { 3242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Some mutation occurred in accessor. Abort "fast" path. 3243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return IndexOfValueSlowPath(isolate, object, value, k + 1, length); 3244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 3245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else if (value->StrictEquals(*element_k)) { 3246f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(k); 3247f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 3248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 3249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Just<int64_t>(-1); 3250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 325169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 325269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 325369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SlowSloppyArgumentsElementsAccessor 3255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : public SloppyArgumentsElementsAccessor< 3256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, 3257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > { 32583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 3259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit SlowSloppyArgumentsElementsAccessor(const char* name) 3260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : SloppyArgumentsElementsAccessor< 3261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, 3262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} 326369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void DeleteFromArguments(Handle<JSObject> obj, uint32_t entry) { 3265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); 3266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SeededNumberDictionary> dict( 3267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SeededNumberDictionary::cast(parameter_map->get(1))); 3268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(verwaest): Remove reliance on index in Shrink. 3269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t index = GetIndexForEntryImpl(*dict, entry); 3270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, entry); 3271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(result); 327213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(result->IsTrue(dict->GetIsolate())); 3273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArray> new_elements = 3274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SeededNumberDictionary::Shrink(dict, index); 3275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameter_map->set(1, *new_elements); 3276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void AddImpl(Handle<JSObject> object, uint32_t index, 3279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> value, PropertyAttributes attributes, 3280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t new_capacity) { 3281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); 3282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> old_elements( 3283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArrayBase::cast(parameter_map->get(1))); 3284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SeededNumberDictionary> dictionary = 3285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch old_elements->IsSeededNumberDictionary() 3286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? Handle<SeededNumberDictionary>::cast(old_elements) 3287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : JSObject::NormalizeElements(object); 328862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PropertyDetails details(kData, attributes, 0, PropertyCellType::kNoCell); 3289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SeededNumberDictionary> new_dictionary = 329062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch SeededNumberDictionary::AddNumberEntry(dictionary, index, value, 329162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch details, object); 3292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (attributes != NONE) object->RequireSlowElements(*new_dictionary); 3293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (*dictionary != *new_dictionary) { 3294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray::cast(object->elements())->set(1, *new_dictionary); 3295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReconfigureImpl(Handle<JSObject> object, 3299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> store, uint32_t entry, 3300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> value, 3301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAttributes attributes) { 3302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store); 3303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = parameter_map->length() - 2; 330413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Isolate* isolate = store->GetIsolate(); 3305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (entry < length) { 3306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* probe = parameter_map->get(entry + 2); 330713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!probe->IsTheHole(isolate)); 3308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Context* context = Context::cast(parameter_map->get(0)); 3309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int context_entry = Smi::cast(probe)->value(); 331013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!context->get(context_entry)->IsTheHole(isolate)); 3311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch context->set(context_entry, *value); 3312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Redefining attributes of an aliased element destroys fast aliasing. 331462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch parameter_map->set_the_hole(isolate, entry + 2); 3315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // For elements that are still writable we re-establish slow aliasing. 3316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((attributes & READ_ONLY) == 0) { 3317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value = isolate->factory()->NewAliasedArgumentsEntry(context_entry); 3318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 332062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PropertyDetails details(kData, attributes, 0, PropertyCellType::kNoCell); 3321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SeededNumberDictionary> arguments( 332213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SeededNumberDictionary::cast(parameter_map->get(1)), isolate); 3323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch arguments = SeededNumberDictionary::AddNumberEntry( 332462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch arguments, entry, value, details, object); 3325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the attributes were NONE, we would have called set rather than 3326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // reconfigure. 3327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(NONE, attributes); 3328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object->RequireSlowElements(*arguments); 3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameter_map->set(1, *arguments); 3330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> arguments( 333213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch FixedArrayBase::cast(parameter_map->get(1)), isolate); 3333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DictionaryElementsAccessor::ReconfigureImpl( 3334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object, arguments, entry - length, value, attributes); 3335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 3338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 33393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass FastSloppyArgumentsElementsAccessor 3341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : public SloppyArgumentsElementsAccessor< 3342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor, 3343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> > { 3344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 3345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit FastSloppyArgumentsElementsAccessor(const char* name) 3346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : SloppyArgumentsElementsAccessor< 3347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FastSloppyArgumentsElementsAccessor, 3348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FastHoleyObjectElementsAccessor, 3349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} 3350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3351bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch static Handle<FixedArray> GetArguments(Isolate* isolate, 3352bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch FixedArrayBase* backing_store) { 3353bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch FixedArray* parameter_map = FixedArray::cast(backing_store); 3354bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Handle<FixedArray>(FixedArray::cast(parameter_map->get(1)), isolate); 3355bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 3356bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 3357bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, uint32_t start, 3358bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch uint32_t end) { 3359bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Isolate* isolate = receiver->GetIsolate(); 3360bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch uint32_t result_len = end < start ? 0u : end - start; 3361bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Handle<JSArray> result_array = isolate->factory()->NewJSArray( 3362bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch FAST_HOLEY_ELEMENTS, result_len, result_len); 3363bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DisallowHeapAllocation no_gc; 3364bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch FixedArray* elements = FixedArray::cast(result_array->elements()); 3365bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch FixedArray* parameters = FixedArray::cast(receiver->elements()); 3366bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch uint32_t insertion_index = 0; 3367bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch for (uint32_t i = start; i < end; i++) { 3368c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t entry = GetEntryForIndexImpl(isolate, *receiver, parameters, i, 3369c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ALL_PROPERTIES); 3370c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (entry != kMaxUInt32 && HasEntryImpl(isolate, parameters, entry)) { 337162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch elements->set(insertion_index, *GetImpl(isolate, parameters, entry)); 3372bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 337362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch elements->set_the_hole(isolate, insertion_index); 3374bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 3375bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch insertion_index++; 3376bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 3377bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return result_array; 3378bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 3379bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 33803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Handle<SeededNumberDictionary> NormalizeImpl( 33813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSObject> object, Handle<FixedArrayBase> elements) { 3382bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Handle<FixedArray> arguments = 3383bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GetArguments(elements->GetIsolate(), *elements); 33843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return FastHoleyObjectElementsAccessor::NormalizeImpl(object, arguments); 33853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 33863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void DeleteFromArguments(Handle<JSObject> obj, uint32_t entry) { 3388bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Handle<FixedArray> arguments = 3389bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GetArguments(obj->GetIsolate(), obj->elements()); 3390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FastHoleyObjectElementsAccessor::DeleteCommon(obj, entry, arguments); 3391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void AddImpl(Handle<JSObject> object, uint32_t index, 3394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> value, PropertyAttributes attributes, 3395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t new_capacity) { 3396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(NONE, attributes); 3397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); 3398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> old_elements( 3399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArrayBase::cast(parameter_map->get(1))); 3400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (old_elements->IsSeededNumberDictionary() || 3401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<uint32_t>(old_elements->length()) < new_capacity) { 3402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GrowCapacityAndConvertImpl(object, new_capacity); 3403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 3405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // For fast holey objects, the entry equals the index. The code above made 3406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // sure that there's enough space to store the value. We cannot convert 3407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // index to entry explicitly since the slot still contains the hole, so the 3408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // current EntryForIndex would indicate that it is "absent" by returning 3409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // kMaxUInt32. 3410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FastHoleyObjectElementsAccessor::SetImpl(arguments, index, *value); 3411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReconfigureImpl(Handle<JSObject> object, 3414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> store, uint32_t entry, 3415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> value, 3416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAttributes attributes) { 3417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SeededNumberDictionary> dictionary = 3418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::NormalizeElements(object); 3419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FixedArray::cast(*store)->set(1, *dictionary); 3420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length = static_cast<uint32_t>(store->length()) - 2; 3421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (entry >= length) { 3422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch entry = dictionary->FindEntry(entry - length) + length; 342369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 3424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SlowSloppyArgumentsElementsAccessor::ReconfigureImpl(object, store, entry, 3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch value, attributes); 342669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 342769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 3429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FixedArrayBase* to, ElementsKind from_kind, 3430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier uint32_t to_start, int packed_size, 3431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int copy_size) { 3432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!to->IsDictionary()); 3433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) { 3434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS, 3435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch to_start, copy_size); 343669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 3437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(FAST_SLOPPY_ARGUMENTS_ELEMENTS, from_kind); 3438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CopyObjectToObjectElements(from, FAST_HOLEY_ELEMENTS, from_start, to, 3439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FAST_HOLEY_ELEMENTS, to_start, copy_size); 344069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 344169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 344269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void GrowCapacityAndConvertImpl(Handle<JSObject> object, 3444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t capacity) { 3445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); 3446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArray> old_elements(FixedArray::cast(parameter_map->get(1))); 3447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind from_kind = object->GetElementsKind(); 3448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This method should only be called if there's a reason to update the 3449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // elements. 3450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS || 3451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<uint32_t>(old_elements->length()) < capacity); 3452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> elements = 3453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ConvertElementsWithCapacity(object, old_elements, from_kind, capacity); 3454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> new_map = JSObject::GetElementsTransitionMap( 3455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object, FAST_SLOPPY_ARGUMENTS_ELEMENTS); 3456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::MigrateToMap(object, new_map); 3457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch parameter_map->set(1, *elements); 3458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::ValidateElements(object); 345969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 346069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 346169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3462bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtemplate <typename Subclass, typename BackingStoreAccessor, typename KindTraits> 3463109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass StringWrapperElementsAccessor 3464bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch : public ElementsAccessorBase<Subclass, KindTraits> { 3465109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch public: 3466109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch explicit StringWrapperElementsAccessor(const char* name) 3467bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch : ElementsAccessorBase<Subclass, KindTraits>(name) { 3468109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch USE(KindTraits::Kind); 3469109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3470109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 347162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static Handle<Object> GetInternalImpl(Handle<JSObject> holder, 347262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t entry) { 347362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return GetImpl(holder, entry); 347462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 347562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 3476109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) { 3477109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Isolate* isolate = holder->GetIsolate(); 3478109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<String> string(GetString(*holder), isolate); 3479109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t length = static_cast<uint32_t>(string->length()); 3480109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (entry < length) { 3481109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return isolate->factory()->LookupSingleCharacterStringFromCode( 3482109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch String::Flatten(string)->Get(entry)); 3483109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 348462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return BackingStoreAccessor::GetImpl(isolate, holder->elements(), 348562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch entry - length); 348662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 348762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 348862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase* elements, 348962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch uint32_t entry) { 349062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UNREACHABLE(); 349162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Handle<Object>(); 3492109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3493109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3494109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { 3495109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t length = static_cast<uint32_t>(GetString(holder)->length()); 3496109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (entry < length) { 3497109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PropertyAttributes attributes = 3498109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); 349962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return PropertyDetails(kData, attributes, 0, PropertyCellType::kNoCell); 3500109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3501109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return BackingStoreAccessor::GetDetailsImpl(holder, entry - length); 3502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3503109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3504c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, 3505109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArrayBase* backing_store, 3506109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t index, PropertyFilter filter) { 3507109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t length = static_cast<uint32_t>(GetString(holder)->length()); 3508109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (index < length) return index; 3509109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t backing_store_entry = BackingStoreAccessor::GetEntryForIndexImpl( 3510c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate, holder, backing_store, index, filter); 3511109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (backing_store_entry == kMaxUInt32) return kMaxUInt32; 3512109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(backing_store_entry < kMaxUInt32 - length); 3513109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return backing_store_entry + length; 3514109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3515109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3516109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static void DeleteImpl(Handle<JSObject> holder, uint32_t entry) { 3517109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t length = static_cast<uint32_t>(GetString(*holder)->length()); 3518109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (entry < length) { 3519109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return; // String contents can't be deleted. 3520109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3521109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch BackingStoreAccessor::DeleteImpl(holder, entry - length); 3522109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3523109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3524109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static void SetImpl(Handle<JSObject> holder, uint32_t entry, Object* value) { 3525109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t length = static_cast<uint32_t>(GetString(*holder)->length()); 3526109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (entry < length) { 3527109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return; // String contents are read-only. 3528109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3529109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch BackingStoreAccessor::SetImpl(holder->elements(), entry - length, value); 3530109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3531109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3532109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static void AddImpl(Handle<JSObject> object, uint32_t index, 3533109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> value, PropertyAttributes attributes, 3534109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t new_capacity) { 3535109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(index >= static_cast<uint32_t>(GetString(*object)->length())); 3536109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Explicitly grow fast backing stores if needed. Dictionaries know how to 3537109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // extend their capacity themselves. 3538109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (KindTraits::Kind == FAST_STRING_WRAPPER_ELEMENTS && 3539109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch (object->GetElementsKind() == SLOW_STRING_WRAPPER_ELEMENTS || 3540109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch BackingStoreAccessor::GetCapacityImpl(*object, object->elements()) != 3541109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch new_capacity)) { 3542bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch GrowCapacityAndConvertImpl(object, new_capacity); 3543109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3544109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch BackingStoreAccessor::AddImpl(object, index, value, attributes, 3545109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch new_capacity); 3546109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3547109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3548109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static void ReconfigureImpl(Handle<JSObject> object, 3549109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedArrayBase> store, uint32_t entry, 3550109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> value, 3551109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PropertyAttributes attributes) { 3552109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t length = static_cast<uint32_t>(GetString(*object)->length()); 3553109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (entry < length) { 3554109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return; // String contents can't be reconfigured. 3555109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3556109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch BackingStoreAccessor::ReconfigureImpl(object, store, entry - length, value, 3557109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch attributes); 3558109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3560109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, 3561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch KeyAccumulator* accumulator, 3562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AddKeyConversion convert) { 3563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Isolate* isolate = receiver->GetIsolate(); 3564109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<String> string(GetString(*receiver), isolate); 3565109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch string = String::Flatten(string); 3566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t length = static_cast<uint32_t>(string->length()); 3567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (uint32_t i = 0; i < length; i++) { 3568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch accumulator->AddKey( 3569109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate->factory()->LookupSingleCharacterStringFromCode( 3570109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch string->Get(i)), 3571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch convert); 3572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator, 3574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch convert); 3575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3577109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static void CollectElementIndicesImpl(Handle<JSObject> object, 3578109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedArrayBase> backing_store, 3579bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch KeyAccumulator* keys) { 35803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t length = GetString(*object)->length(); 358113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Factory* factory = keys->isolate()->factory(); 35823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (uint32_t i = 0; i < length; i++) { 358313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch keys->AddKey(factory->NewNumberFromUint(i)); 3584109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3585bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, 3586bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch keys); 3587bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 3588bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 3589bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch static void GrowCapacityAndConvertImpl(Handle<JSObject> object, 3590bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch uint32_t capacity) { 3591bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Handle<FixedArrayBase> old_elements(object->elements()); 3592bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ElementsKind from_kind = object->GetElementsKind(); 3593bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // This method should only be called if there's a reason to update the 3594bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // elements. 3595bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(from_kind == SLOW_STRING_WRAPPER_ELEMENTS || 3596bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch static_cast<uint32_t>(old_elements->length()) < capacity); 3597bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Subclass::BasicGrowCapacityAndConvertImpl(object, old_elements, from_kind, 3598bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch FAST_STRING_WRAPPER_ELEMENTS, 3599bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch capacity); 3600109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3601109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3602109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 3603109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArrayBase* to, ElementsKind from_kind, 3604109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch uint32_t to_start, int packed_size, 3605109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int copy_size) { 3606bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(!to->IsDictionary()); 3607bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (from_kind == SLOW_STRING_WRAPPER_ELEMENTS) { 3608bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS, 3609bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch to_start, copy_size); 3610bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 3611bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK_EQ(FAST_STRING_WRAPPER_ELEMENTS, from_kind); 3612bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CopyObjectToObjectElements(from, FAST_HOLEY_ELEMENTS, from_start, to, 3613bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch FAST_HOLEY_ELEMENTS, to_start, copy_size); 3614bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 3615109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3616109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3617c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static uint32_t NumberOfElementsImpl(JSObject* object, 3618c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch FixedArrayBase* backing_store) { 3619c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch uint32_t length = GetString(object)->length(); 3620c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return length + 3621c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch BackingStoreAccessor::NumberOfElementsImpl(object, backing_store); 3622c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 3623c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 3624109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch private: 3625109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static String* GetString(JSObject* holder) { 3626109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(holder->IsJSValue()); 3627109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch JSValue* js_value = JSValue::cast(holder); 3628109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(js_value->value()->IsString()); 3629109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return String::cast(js_value->value()); 3630109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3631109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}; 3632109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3633109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass FastStringWrapperElementsAccessor 3634109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : public StringWrapperElementsAccessor< 3635109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FastStringWrapperElementsAccessor, FastHoleyObjectElementsAccessor, 3636109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ElementsKindTraits<FAST_STRING_WRAPPER_ELEMENTS>> { 3637109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch public: 3638109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch explicit FastStringWrapperElementsAccessor(const char* name) 3639109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : StringWrapperElementsAccessor< 3640109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FastStringWrapperElementsAccessor, FastHoleyObjectElementsAccessor, 3641109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ElementsKindTraits<FAST_STRING_WRAPPER_ELEMENTS>>(name) {} 36423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 36433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static Handle<SeededNumberDictionary> NormalizeImpl( 36443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSObject> object, Handle<FixedArrayBase> elements) { 36453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return FastHoleyObjectElementsAccessor::NormalizeImpl(object, elements); 36463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 3647109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}; 3648109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3649109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass SlowStringWrapperElementsAccessor 3650109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : public StringWrapperElementsAccessor< 3651109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch SlowStringWrapperElementsAccessor, DictionaryElementsAccessor, 3652109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ElementsKindTraits<SLOW_STRING_WRAPPER_ELEMENTS>> { 3653109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch public: 3654109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch explicit SlowStringWrapperElementsAccessor(const char* name) 3655109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : StringWrapperElementsAccessor< 3656109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch SlowStringWrapperElementsAccessor, DictionaryElementsAccessor, 3657109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ElementsKindTraits<SLOW_STRING_WRAPPER_ELEMENTS>>(name) {} 3658109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3659109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch static bool HasAccessorsImpl(JSObject* holder, 3660109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArrayBase* backing_store) { 3661109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return DictionaryElementsAccessor::HasAccessorsImpl(holder, backing_store); 3662109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3663109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}; 366469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace 366669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 366769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t index, 3669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool allow_appending) { 3670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DisallowHeapAllocation no_allocation; 3671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* raw_length = NULL; 3672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const char* elements_type = "array"; 3673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (obj->IsJSArray()) { 3674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSArray* array = JSArray::cast(*obj); 3675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw_length = array->length(); 3676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raw_length = Smi::FromInt(obj->elements()->length()); 3678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements_type = "object"; 36793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 36803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (raw_length->IsNumber()) { 3682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double n = raw_length->Number(); 3683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (FastI2D(FastD2UI(n)) == n) { 3684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t int32_length = DoubleToInt32(n); 3685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t compare_length = static_cast<uint32_t>(int32_length); 3686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (allow_appending) compare_length++; 3687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (index >= compare_length) { 3688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrintF("[OOB %s %s (%s length = %d, element accessed = %d) in ", 3689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements_type, op, elements_type, static_cast<int>(int32_length), 3690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<int>(index)); 3691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TraceTopFrame(obj->GetIsolate()); 3692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrintF("]\n"); 3693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 36943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 3695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrintF("[%s elements length not integer value in ", elements_type); 3696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TraceTopFrame(obj->GetIsolate()); 3697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrintF("]\n"); 36983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrintF("[%s elements length not a number in ", elements_type); 3701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TraceTopFrame(obj->GetIsolate()); 3702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrintF("]\n"); 37033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 37043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 37053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMaybeHandle<Object> ArrayConstructInitializeElements(Handle<JSArray> array, 3708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Arguments* args) { 3709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (args->length() == 0) { 3710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Optimize the case where there are no parameters passed. 3711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSArray::Initialize(array, JSArray::kPreallocatedArrayElements); 3712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return array; 3713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 371462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (args->length() == 1 && args->at(0)->IsNumber()) { 3715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t length; 371662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!args->at(0)->ToArrayLength(&length)) { 3717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ThrowArrayLengthRangeError(array->GetIsolate()); 3718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Optimize the case where there is one argument and the argument is a small 3721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // smi. 3722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (length > 0 && length < JSArray::kInitialMaxFastElementArray) { 3723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind elements_kind = array->GetElementsKind(); 3724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSArray::Initialize(array, length, length); 3725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!IsFastHoleyElementsKind(elements_kind)) { 3727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements_kind = GetHoleyElementsKind(elements_kind); 3728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::TransitionElementsKind(array, elements_kind); 3729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (length == 0) { 3731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSArray::Initialize(array, JSArray::kPreallocatedArrayElements); 3732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Take the argument as the length. 3734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSArray::Initialize(array, 0); 3735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSArray::SetLength(array, length); 3736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return array; 3738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = array->GetIsolate()->factory(); 3741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set length and elements on the array. 3743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int number_of_elements = args->length(); 3744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSObject::EnsureCanContainElements( 3745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array, args, 0, number_of_elements, ALLOW_CONVERTED_DOUBLE_ELEMENTS); 3746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate an appropriately typed elements array. 3748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind = array->GetElementsKind(); 3749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArrayBase> elms; 3750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsFastDoubleElementsKind(elements_kind)) { 3751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elms = Handle<FixedArrayBase>::cast( 3752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewFixedDoubleArray(number_of_elements)); 3753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch elms = Handle<FixedArrayBase>::cast( 3755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewFixedArrayWithHoles(number_of_elements)); 3756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fill in the content 3759bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch switch (elements_kind) { 3760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_HOLEY_SMI_ELEMENTS: 3761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_SMI_ELEMENTS: { 3762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> smi_elms = Handle<FixedArray>::cast(elms); 3763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int entry = 0; entry < number_of_elements; entry++) { 3764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch smi_elms->set(entry, (*args)[entry], SKIP_WRITE_BARRIER); 3765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 3767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_HOLEY_ELEMENTS: 3769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_ELEMENTS: { 3770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 3771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); 3772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedArray> object_elms = Handle<FixedArray>::cast(elms); 3773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int entry = 0; entry < number_of_elements; entry++) { 3774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object_elms->set(entry, (*args)[entry], mode); 3775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 3777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_HOLEY_DOUBLE_ELEMENTS: 3779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case FAST_DOUBLE_ELEMENTS: { 3780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedDoubleArray> double_elms = 3781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<FixedDoubleArray>::cast(elms); 3782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int entry = 0; entry < number_of_elements; entry++) { 3783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch double_elms->set(entry, (*args)[entry]->Number()); 3784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 3786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 3788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 3789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 3790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array->set_elements(*elms); 3793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch array->set_length(Smi::FromInt(number_of_elements)); 3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return array; 3795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ElementsAccessor::InitializeOncePerProcess() { 3799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static ElementsAccessor* accessor_array[] = { 3800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind), 3801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ELEMENTS_LIST(ACCESSOR_ARRAY) 3802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef ACCESSOR_ARRAY 3803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 3804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) == 3806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kElementsKindCount); 3807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements_accessors_ = accessor_array; 3809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ElementsAccessor::TearDown() { 3813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (elements_accessors_ == NULL) return; 3814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; 3815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ELEMENTS_LIST(ACCESSOR_DELETE) 3816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef ACCESSOR_DELETE 3817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements_accessors_ = NULL; 3818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<JSArray> ElementsAccessor::Concat(Isolate* isolate, Arguments* args, 3821bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch uint32_t concat_size, 3822bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch uint32_t result_len) { 38233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ElementsKind result_elements_kind = GetInitialFastElementsKind(); 3824bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch bool has_raw_doubles = false; 3825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 3826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DisallowHeapAllocation no_gc; 38273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bool is_holey = false; 3828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (uint32_t i = 0; i < concat_size; i++) { 3829bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Object* arg = (*args)[i]; 3830bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ElementsKind arg_kind = JSArray::cast(arg)->GetElementsKind(); 38313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch has_raw_doubles = has_raw_doubles || IsFastDoubleElementsKind(arg_kind); 3832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch is_holey = is_holey || IsFastHoleyElementsKind(arg_kind); 38333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch result_elements_kind = 38343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch GetMoreGeneralElementsKind(result_elements_kind, arg_kind); 3835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_holey) { 38373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch result_elements_kind = GetHoleyElementsKind(result_elements_kind); 3838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If a double array is concatted into a fast elements array, the fast 3842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // elements array needs to be initialized to contain proper holes, since 3843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // boxing doubles may cause incremental marking. 38443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bool requires_double_boxing = 38453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch has_raw_doubles && !IsFastDoubleElementsKind(result_elements_kind); 38463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ArrayStorageAllocationMode mode = requires_double_boxing 38473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE 38483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch : DONT_INITIALIZE_ARRAY_ELEMENTS; 3849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSArray> result_array = isolate->factory()->NewJSArray( 38503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch result_elements_kind, result_len, result_len, mode); 3851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (result_len == 0) return result_array; 38523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 38533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t insertion_index = 0; 3854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<FixedArrayBase> storage(result_array->elements(), isolate); 38553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ElementsAccessor* accessor = ElementsAccessor::ForKind(result_elements_kind); 3856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (uint32_t i = 0; i < concat_size; i++) { 3857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // It is crucial to keep |array| in a raw pointer form to avoid 3858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // performance degradation. 3859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSArray* array = JSArray::cast((*args)[i]); 38603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint32_t len = 0; 38613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch array->length()->ToArrayLength(&len); 38623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (len == 0) continue; 38633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ElementsKind from_kind = array->GetElementsKind(); 38643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch accessor->CopyElements(array, 0, from_kind, storage, insertion_index, len); 38653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch insertion_index += len; 3866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 38683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(insertion_index, result_len); 3869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result_array; 3870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 3873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 3874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 3875