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