v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
elements.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include "v8.h"
29 
30 #include "arguments.h"
31 #include "objects.h"
32 #include "elements.h"
33 #include "utils.h"
34 #include "v8conversions.h"
35 
36 // Each concrete ElementsAccessor can handle exactly one ElementsKind,
37 // several abstract ElementsAccessor classes are used to allow sharing
38 // common code.
39 //
40 // Inheritance hierarchy:
41 // - ElementsAccessorBase (abstract)
42 // - FastElementsAccessor (abstract)
43 // - FastSmiOrObjectElementsAccessor
44 // - FastPackedSmiElementsAccessor
45 // - FastHoleySmiElementsAccessor
46 // - FastPackedObjectElementsAccessor
47 // - FastHoleyObjectElementsAccessor
48 // - FastDoubleElementsAccessor
49 // - FastPackedDoubleElementsAccessor
50 // - FastHoleyDoubleElementsAccessor
51 // - TypedElementsAccessor: template, with instantiations:
52 // - ExternalInt8ElementsAccessor
53 // - ExternalUint8ElementsAccessor
54 // - ExternalInt16ElementsAccessor
55 // - ExternalUint16ElementsAccessor
56 // - ExternalInt32ElementsAccessor
57 // - ExternalUint32ElementsAccessor
58 // - ExternalFloat32ElementsAccessor
59 // - ExternalFloat64ElementsAccessor
60 // - ExternalUint8ClampedElementsAccessor
61 // - FixedUint8ElementsAccessor
62 // - FixedInt8ElementsAccessor
63 // - FixedUint16ElementsAccessor
64 // - FixedInt16ElementsAccessor
65 // - FixedUint32ElementsAccessor
66 // - FixedInt32ElementsAccessor
67 // - FixedFloat32ElementsAccessor
68 // - FixedFloat64ElementsAccessor
69 // - FixedUint8ClampedElementsAccessor
70 // - DictionaryElementsAccessor
71 // - SloppyArgumentsElementsAccessor
72 
73 
74 namespace v8 {
75 namespace internal {
76 
77 
78 static const int kPackedSizeNotKnown = -1;
79 
80 
81 // First argument in list is the accessor class, the second argument is the
82 // accessor ElementsKind, and the third is the backing store class. Use the
83 // fast element handler for smi-only arrays. The implementation is currently
84 // identical. Note that the order must match that of the ElementsKind enum for
85 // the |accessor_array[]| below to work.
86 #define ELEMENTS_LIST(V) \
87  V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \
88  V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, \
89  FixedArray) \
90  V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \
91  V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \
92  V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, \
93  FixedDoubleArray) \
94  V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \
95  FixedDoubleArray) \
96  V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, \
97  SeededNumberDictionary) \
98  V(SloppyArgumentsElementsAccessor, SLOPPY_ARGUMENTS_ELEMENTS, \
99  FixedArray) \
100  V(ExternalInt8ElementsAccessor, EXTERNAL_INT8_ELEMENTS, \
101  ExternalInt8Array) \
102  V(ExternalUint8ElementsAccessor, \
103  EXTERNAL_UINT8_ELEMENTS, ExternalUint8Array) \
104  V(ExternalInt16ElementsAccessor, EXTERNAL_INT16_ELEMENTS, \
105  ExternalInt16Array) \
106  V(ExternalUint16ElementsAccessor, \
107  EXTERNAL_UINT16_ELEMENTS, ExternalUint16Array) \
108  V(ExternalInt32ElementsAccessor, EXTERNAL_INT32_ELEMENTS, \
109  ExternalInt32Array) \
110  V(ExternalUint32ElementsAccessor, \
111  EXTERNAL_UINT32_ELEMENTS, ExternalUint32Array) \
112  V(ExternalFloat32ElementsAccessor, \
113  EXTERNAL_FLOAT32_ELEMENTS, ExternalFloat32Array) \
114  V(ExternalFloat64ElementsAccessor, \
115  EXTERNAL_FLOAT64_ELEMENTS, ExternalFloat64Array) \
116  V(ExternalUint8ClampedElementsAccessor, \
117  EXTERNAL_UINT8_CLAMPED_ELEMENTS, \
118  ExternalUint8ClampedArray) \
119  V(FixedUint8ElementsAccessor, UINT8_ELEMENTS, FixedUint8Array) \
120  V(FixedInt8ElementsAccessor, INT8_ELEMENTS, FixedInt8Array) \
121  V(FixedUint16ElementsAccessor, UINT16_ELEMENTS, FixedUint16Array) \
122  V(FixedInt16ElementsAccessor, INT16_ELEMENTS, FixedInt16Array) \
123  V(FixedUint32ElementsAccessor, UINT32_ELEMENTS, FixedUint32Array) \
124  V(FixedInt32ElementsAccessor, INT32_ELEMENTS, FixedInt32Array) \
125  V(FixedFloat32ElementsAccessor, FLOAT32_ELEMENTS, FixedFloat32Array) \
126  V(FixedFloat64ElementsAccessor, FLOAT64_ELEMENTS, FixedFloat64Array) \
127  V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \
128  FixedUint8ClampedArray)
129 
130 
131 template<ElementsKind Kind> class ElementsKindTraits {
132  public:
134 };
135 
136 #define ELEMENTS_TRAITS(Class, KindParam, Store) \
137 template<> class ElementsKindTraits<KindParam> { \
138  public: \
139  static const ElementsKind Kind = KindParam; \
140  typedef Store BackingStore; \
141 };
143 #undef ELEMENTS_TRAITS
144 
145 
146 ElementsAccessor** ElementsAccessor::elements_accessors_;
147 
148 
149 static bool HasKey(FixedArray* array, Object* key) {
150  int len0 = array->length();
151  for (int i = 0; i < len0; i++) {
152  Object* element = array->get(i);
153  if (element->IsSmi() && element == key) return true;
154  if (element->IsString() &&
155  key->IsString() && String::cast(element)->Equals(String::cast(key))) {
156  return true;
157  }
158  }
159  return false;
160 }
161 
162 
163 static Handle<Object> ThrowArrayLengthRangeError(Isolate* isolate) {
164  isolate->Throw(
165  *isolate->factory()->NewRangeError("invalid_array_length",
166  HandleVector<Object>(NULL, 0)));
167  return Handle<Object>();
168 }
169 
170 
171 static void CopyObjectToObjectElements(Handle<FixedArrayBase> from_base,
172  ElementsKind from_kind,
173  uint32_t from_start,
174  Handle<FixedArrayBase> to_base,
175  ElementsKind to_kind,
176  uint32_t to_start,
177  int raw_copy_size) {
178  ASSERT(to_base->map() !=
179  from_base->GetIsolate()->heap()->fixed_cow_array_map());
180  DisallowHeapAllocation no_allocation;
181  int copy_size = raw_copy_size;
182  if (raw_copy_size < 0) {
183  ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
185  copy_size = Min(from_base->length() - from_start,
186  to_base->length() - to_start);
188  int start = to_start + copy_size;
189  int length = to_base->length() - start;
190  if (length > 0) {
191  Heap* heap = from_base->GetHeap();
192  MemsetPointer(Handle<FixedArray>::cast(to_base)->data_start() + start,
193  heap->the_hole_value(), length);
194  }
195  }
196  }
197  ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
198  (copy_size + static_cast<int>(from_start)) <= from_base->length());
199  if (copy_size == 0) return;
200  Handle<FixedArray> from = Handle<FixedArray>::cast(from_base);
201  Handle<FixedArray> to = Handle<FixedArray>::cast(to_base);
204  Address to_address = to->address() + FixedArray::kHeaderSize;
205  Address from_address = from->address() + FixedArray::kHeaderSize;
206  CopyWords(reinterpret_cast<Object**>(to_address) + to_start,
207  reinterpret_cast<Object**>(from_address) + from_start,
208  static_cast<size_t>(copy_size));
209  if (IsFastObjectElementsKind(from_kind) &&
210  IsFastObjectElementsKind(to_kind)) {
211  Heap* heap = from->GetHeap();
212  if (!heap->InNewSpace(*to)) {
213  heap->RecordWrites(to->address(),
214  to->OffsetOfElementAt(to_start),
215  copy_size);
216  }
217  heap->incremental_marking()->RecordWrites(*to);
218  }
219 }
220 
221 
222 static void CopyDictionaryToObjectElements(Handle<FixedArrayBase> from_base,
223  uint32_t from_start,
224  Handle<FixedArrayBase> to_base,
225  ElementsKind to_kind,
226  uint32_t to_start,
227  int raw_copy_size) {
228  Handle<SeededNumberDictionary> from =
230  DisallowHeapAllocation no_allocation;
231  int copy_size = raw_copy_size;
232  Heap* heap = from->GetHeap();
233  if (raw_copy_size < 0) {
234  ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
236  copy_size = from->max_number_key() + 1 - from_start;
238  int start = to_start + copy_size;
239  int length = to_base->length() - start;
240  if (length > 0) {
241  Heap* heap = from->GetHeap();
242  MemsetPointer(Handle<FixedArray>::cast(to_base)->data_start() + start,
243  heap->the_hole_value(), length);
244  }
245  }
246  }
247  ASSERT(*to_base != *from_base);
249  if (copy_size == 0) return;
250  Handle<FixedArray> to = Handle<FixedArray>::cast(to_base);
251  uint32_t to_length = to->length();
252  if (to_start + copy_size > to_length) {
253  copy_size = to_length - to_start;
254  }
255  for (int i = 0; i < copy_size; i++) {
256  int entry = from->FindEntry(i + from_start);
257  if (entry != SeededNumberDictionary::kNotFound) {
258  Object* value = from->ValueAt(entry);
259  ASSERT(!value->IsTheHole());
260  to->set(i + to_start, value, SKIP_WRITE_BARRIER);
261  } else {
262  to->set_the_hole(i + to_start);
263  }
264  }
265  if (IsFastObjectElementsKind(to_kind)) {
266  if (!heap->InNewSpace(*to)) {
267  heap->RecordWrites(to->address(),
268  to->OffsetOfElementAt(to_start),
269  copy_size);
270  }
271  heap->incremental_marking()->RecordWrites(*to);
272  }
273 }
274 
275 
276 static void CopyDoubleToObjectElements(Handle<FixedArrayBase> from_base,
277  uint32_t from_start,
278  Handle<FixedArrayBase> to_base,
279  ElementsKind to_kind,
280  uint32_t to_start,
281  int raw_copy_size) {
283  int copy_size = raw_copy_size;
284  if (raw_copy_size < 0) {
285  ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
287  copy_size = Min(from_base->length() - from_start,
288  to_base->length() - to_start);
290  // Also initialize the area that will be copied over since HeapNumber
291  // allocation below can cause an incremental marking step, requiring all
292  // existing heap objects to be propertly initialized.
293  int start = to_start;
294  int length = to_base->length() - start;
295  if (length > 0) {
296  Heap* heap = from_base->GetHeap();
297  MemsetPointer(Handle<FixedArray>::cast(to_base)->data_start() + start,
298  heap->the_hole_value(), length);
299  }
300  }
301  }
302  ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
303  (copy_size + static_cast<int>(from_start)) <= from_base->length());
304  if (copy_size == 0) return;
305  Handle<FixedDoubleArray> from = Handle<FixedDoubleArray>::cast(from_base);
306  Handle<FixedArray> to = Handle<FixedArray>::cast(to_base);
307  for (int i = 0; i < copy_size; ++i) {
308  HandleScope scope(from_base->GetIsolate());
309  if (IsFastSmiElementsKind(to_kind)) {
310  UNIMPLEMENTED();
311  } else {
313  Handle<Object> value = from->get_as_handle(i + from_start);
314  to->set(i + to_start, *value, UPDATE_WRITE_BARRIER);
315  }
316  }
317 }
318 
319 
320 static void CopyDoubleToDoubleElements(Handle<FixedArrayBase> from_base,
321  uint32_t from_start,
322  Handle<FixedArrayBase> to_base,
323  uint32_t to_start,
324  int raw_copy_size) {
325  DisallowHeapAllocation no_allocation;
326  int copy_size = raw_copy_size;
327  if (raw_copy_size < 0) {
328  ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
330  copy_size = Min(from_base->length() - from_start,
331  to_base->length() - to_start);
333  for (int i = to_start + copy_size; i < to_base->length(); ++i) {
334  Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i);
335  }
336  }
337  }
338  ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
339  (copy_size + static_cast<int>(from_start)) <= from_base->length());
340  if (copy_size == 0) return;
341  Handle<FixedDoubleArray> from = Handle<FixedDoubleArray>::cast(from_base);
342  Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base);
343  Address to_address = to->address() + FixedDoubleArray::kHeaderSize;
344  Address from_address = from->address() + FixedDoubleArray::kHeaderSize;
345  to_address += kDoubleSize * to_start;
346  from_address += kDoubleSize * from_start;
347  int words_per_double = (kDoubleSize / kPointerSize);
348  CopyWords(reinterpret_cast<Object**>(to_address),
349  reinterpret_cast<Object**>(from_address),
350  static_cast<size_t>(words_per_double * copy_size));
351 }
352 
353 
354 static void CopySmiToDoubleElements(Handle<FixedArrayBase> from_base,
355  uint32_t from_start,
356  Handle<FixedArrayBase> to_base,
357  uint32_t to_start,
358  int raw_copy_size) {
359  DisallowHeapAllocation no_allocation;
360  int copy_size = raw_copy_size;
361  if (raw_copy_size < 0) {
362  ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
364  copy_size = from_base->length() - from_start;
366  for (int i = to_start + copy_size; i < to_base->length(); ++i) {
367  Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i);
368  }
369  }
370  }
371  ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
372  (copy_size + static_cast<int>(from_start)) <= from_base->length());
373  if (copy_size == 0) return;
374  Handle<FixedArray> from = Handle<FixedArray>::cast(from_base);
375  Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base);
376  Handle<Object> the_hole = from->GetIsolate()->factory()->the_hole_value();
377  for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size);
378  from_start < from_end; from_start++, to_start++) {
379  Object* hole_or_smi = from->get(from_start);
380  if (hole_or_smi == *the_hole) {
381  to->set_the_hole(to_start);
382  } else {
383  to->set(to_start, Smi::cast(hole_or_smi)->value());
384  }
385  }
386 }
387 
388 
389 static void CopyPackedSmiToDoubleElements(Handle<FixedArrayBase> from_base,
390  uint32_t from_start,
391  Handle<FixedArrayBase> to_base,
392  uint32_t to_start,
393  int packed_size,
394  int raw_copy_size) {
395  DisallowHeapAllocation no_allocation;
396  int copy_size = raw_copy_size;
397  uint32_t to_end;
398  if (raw_copy_size < 0) {
399  ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
401  copy_size = packed_size - from_start;
403  to_end = to_base->length();
404  for (uint32_t i = to_start + copy_size; i < to_end; ++i) {
405  Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i);
406  }
407  } else {
408  to_end = to_start + static_cast<uint32_t>(copy_size);
409  }
410  } else {
411  to_end = to_start + static_cast<uint32_t>(copy_size);
412  }
413  ASSERT(static_cast<int>(to_end) <= to_base->length());
414  ASSERT(packed_size >= 0 && packed_size <= copy_size);
415  ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
416  (copy_size + static_cast<int>(from_start)) <= from_base->length());
417  if (copy_size == 0) return;
418  Handle<FixedArray> from = Handle<FixedArray>::cast(from_base);
419  Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base);
420  for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size);
421  from_start < from_end; from_start++, to_start++) {
422  Object* smi = from->get(from_start);
423  ASSERT(!smi->IsTheHole());
424  to->set(to_start, Smi::cast(smi)->value());
425  }
426 }
427 
428 
429 static void CopyObjectToDoubleElements(Handle<FixedArrayBase> from_base,
430  uint32_t from_start,
431  Handle<FixedArrayBase> to_base,
432  uint32_t to_start,
433  int raw_copy_size) {
434  DisallowHeapAllocation no_allocation;
435  int copy_size = raw_copy_size;
436  if (raw_copy_size < 0) {
437  ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
439  copy_size = from_base->length() - from_start;
441  for (int i = to_start + copy_size; i < to_base->length(); ++i) {
442  Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i);
443  }
444  }
445  }
446  ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
447  (copy_size + static_cast<int>(from_start)) <= from_base->length());
448  if (copy_size == 0) return;
449  Handle<FixedArray> from = Handle<FixedArray>::cast(from_base);
450  Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base);
451  Handle<Object> the_hole = from->GetIsolate()->factory()->the_hole_value();
452  for (uint32_t from_end = from_start + copy_size;
453  from_start < from_end; from_start++, to_start++) {
454  Object* hole_or_object = from->get(from_start);
455  if (hole_or_object == *the_hole) {
456  to->set_the_hole(to_start);
457  } else {
458  to->set(to_start, hole_or_object->Number());
459  }
460  }
461 }
462 
463 
464 static void CopyDictionaryToDoubleElements(Handle<FixedArrayBase> from_base,
465  uint32_t from_start,
466  Handle<FixedArrayBase> to_base,
467  uint32_t to_start,
468  int raw_copy_size) {
469  Handle<SeededNumberDictionary> from =
471  DisallowHeapAllocation no_allocation;
472  int copy_size = raw_copy_size;
473  if (copy_size < 0) {
474  ASSERT(copy_size == ElementsAccessor::kCopyToEnd ||
476  copy_size = from->max_number_key() + 1 - from_start;
478  for (int i = to_start + copy_size; i < to_base->length(); ++i) {
479  Handle<FixedDoubleArray>::cast(to_base)->set_the_hole(i);
480  }
481  }
482  }
483  if (copy_size == 0) return;
484  Handle<FixedDoubleArray> to = Handle<FixedDoubleArray>::cast(to_base);
485  uint32_t to_length = to->length();
486  if (to_start + copy_size > to_length) {
487  copy_size = to_length - to_start;
488  }
489  for (int i = 0; i < copy_size; i++) {
490  int entry = from->FindEntry(i + from_start);
491  if (entry != SeededNumberDictionary::kNotFound) {
492  to->set(i + to_start, from->ValueAt(entry)->Number());
493  } else {
494  to->set_the_hole(i + to_start);
495  }
496  }
497 }
498 
499 
500 static void TraceTopFrame(Isolate* isolate) {
501  StackFrameIterator it(isolate);
502  if (it.done()) {
503  PrintF("unknown location (no JavaScript frames present)");
504  return;
505  }
506  StackFrame* raw_frame = it.frame();
507  if (raw_frame->is_internal()) {
508  Code* apply_builtin = isolate->builtins()->builtin(
509  Builtins::kFunctionApply);
510  if (raw_frame->unchecked_code() == apply_builtin) {
511  PrintF("apply from ");
512  it.Advance();
513  raw_frame = it.frame();
514  }
515  }
516  JavaScriptFrame::PrintTop(isolate, stdout, false, true);
517 }
518 
519 
520 void CheckArrayAbuse(JSObject* obj, const char* op, uint32_t key,
521  bool allow_appending) {
522  Object* raw_length = NULL;
523  const char* elements_type = "array";
524  if (obj->IsJSArray()) {
525  JSArray* array = JSArray::cast(obj);
526  raw_length = array->length();
527  } else {
528  raw_length = Smi::FromInt(obj->elements()->length());
529  elements_type = "object";
530  }
531 
532  if (raw_length->IsNumber()) {
533  double n = raw_length->Number();
534  if (FastI2D(FastD2UI(n)) == n) {
535  int32_t int32_length = DoubleToInt32(n);
536  uint32_t compare_length = static_cast<uint32_t>(int32_length);
537  if (allow_appending) compare_length++;
538  if (key >= compare_length) {
539  PrintF("[OOB %s %s (%s length = %d, element accessed = %d) in ",
540  elements_type, op, elements_type,
541  static_cast<int>(int32_length),
542  static_cast<int>(key));
543  TraceTopFrame(obj->GetIsolate());
544  PrintF("]\n");
545  }
546  } else {
547  PrintF("[%s elements length not integer value in ", elements_type);
548  TraceTopFrame(obj->GetIsolate());
549  PrintF("]\n");
550  }
551  } else {
552  PrintF("[%s elements length not a number in ", elements_type);
553  TraceTopFrame(obj->GetIsolate());
554  PrintF("]\n");
555  }
556 }
557 
558 
559 // Base class for element handler implementations. Contains the
560 // the common logic for objects with different ElementsKinds.
561 // Subclasses must specialize method for which the element
562 // implementation differs from the base class implementation.
563 //
564 // This class is intended to be used in the following way:
565 //
566 // class SomeElementsAccessor :
567 // public ElementsAccessorBase<SomeElementsAccessor,
568 // BackingStoreClass> {
569 // ...
570 // }
571 //
572 // This is an example of the Curiously Recurring Template Pattern (see
573 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use
574 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and
575 // specialization of SomeElementsAccessor methods).
576 template <typename ElementsAccessorSubclass,
577  typename ElementsTraitsParam>
579  protected:
580  explicit ElementsAccessorBase(const char* name)
581  : ElementsAccessor(name) { }
582 
583  typedef ElementsTraitsParam ElementsTraits;
584  typedef typename ElementsTraitsParam::BackingStore BackingStore;
585 
587  return ElementsTraits::Kind;
588  }
589 
590  static void ValidateContents(JSObject* holder, int length) {
591  }
592 
593  static void ValidateImpl(JSObject* holder) {
594  FixedArrayBase* fixed_array_base = holder->elements();
595  // When objects are first allocated, its elements are Failures.
596  if (fixed_array_base->IsFailure()) return;
597  if (!fixed_array_base->IsHeapObject()) return;
598  // Arrays that have been shifted in place can't be verified.
599  if (fixed_array_base->IsFiller()) return;
600  int length = 0;
601  if (holder->IsJSArray()) {
602  Object* length_obj = JSArray::cast(holder)->length();
603  if (length_obj->IsSmi()) {
604  length = Smi::cast(length_obj)->value();
605  }
606  } else {
607  length = fixed_array_base->length();
608  }
609  ElementsAccessorSubclass::ValidateContents(holder, length);
610  }
611 
612  virtual void Validate(JSObject* holder) V8_FINAL V8_OVERRIDE {
613  ElementsAccessorSubclass::ValidateImpl(holder);
614  }
615 
616  static bool HasElementImpl(Object* receiver,
617  JSObject* holder,
618  uint32_t key,
619  FixedArrayBase* backing_store) {
620  return ElementsAccessorSubclass::GetAttributesImpl(
621  receiver, holder, key, backing_store) != ABSENT;
622  }
623 
624  virtual bool HasElement(Object* receiver,
625  JSObject* holder,
626  uint32_t key,
627  FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE {
628  if (backing_store == NULL) {
629  backing_store = holder->elements();
630  }
631  return ElementsAccessorSubclass::HasElementImpl(
632  receiver, holder, key, backing_store);
633  }
634 
635  // TODO(ishell): Temporary wrapper until handlified.
637  Handle<Object> receiver,
638  Handle<JSObject> holder,
639  uint32_t key,
641  CALL_HEAP_FUNCTION(holder->GetIsolate(),
642  Get(*receiver, *holder, key,
643  backing_store.is_null()
644  ? NULL : *backing_store),
645  Object);
646  }
647 
648  MUST_USE_RESULT virtual MaybeObject* Get(
649  Object* receiver,
650  JSObject* holder,
651  uint32_t key,
652  FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE {
653  if (backing_store == NULL) {
654  backing_store = holder->elements();
655  }
656 
657  if (!IsExternalArrayElementsKind(ElementsTraits::Kind) &&
658  FLAG_trace_js_array_abuse) {
659  CheckArrayAbuse(holder, "elements read", key);
660  }
661 
662  if (IsExternalArrayElementsKind(ElementsTraits::Kind) &&
663  FLAG_trace_external_array_abuse) {
664  CheckArrayAbuse(holder, "external elements read", key);
665  }
666 
667  return ElementsAccessorSubclass::GetImpl(
668  receiver, holder, key, backing_store);
669  }
670 
671  MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
672  JSObject* obj,
673  uint32_t key,
674  FixedArrayBase* backing_store) {
675  return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store))
676  ? BackingStore::cast(backing_store)->get(key)
677  : backing_store->GetHeap()->the_hole_value();
678  }
679 
681  Object* receiver,
682  JSObject* holder,
683  uint32_t key,
684  FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE {
685  if (backing_store == NULL) {
686  backing_store = holder->elements();
687  }
688  return ElementsAccessorSubclass::GetAttributesImpl(
689  receiver, holder, key, backing_store);
690  }
691 
693  Object* receiver,
694  JSObject* obj,
695  uint32_t key,
696  FixedArrayBase* backing_store) {
697  if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) {
698  return ABSENT;
699  }
700  return BackingStore::cast(backing_store)->is_the_hole(key) ? ABSENT : NONE;
701  }
702 
704  Object* receiver,
705  JSObject* holder,
706  uint32_t key,
707  FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE {
708  if (backing_store == NULL) {
709  backing_store = holder->elements();
710  }
711  return ElementsAccessorSubclass::GetTypeImpl(
712  receiver, holder, key, backing_store);
713  }
714 
716  Object* receiver,
717  JSObject* obj,
718  uint32_t key,
719  FixedArrayBase* backing_store) {
720  if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) {
721  return NONEXISTENT;
722  }
723  return BackingStore::cast(backing_store)->is_the_hole(key)
724  ? NONEXISTENT : FIELD;
725  }
726 
728  Object* receiver,
729  JSObject* holder,
730  uint32_t key,
731  FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE {
732  if (backing_store == NULL) {
733  backing_store = holder->elements();
734  }
735  return ElementsAccessorSubclass::GetAccessorPairImpl(
736  receiver, holder, key, backing_store);
737  }
738 
740  Object* receiver,
741  JSObject* obj,
742  uint32_t key,
743  FixedArrayBase* backing_store) {
744  return NULL;
745  }
746 
748  Handle<JSArray> array,
750  return ElementsAccessorSubclass::SetLengthImpl(
751  array, length, handle(array->elements()));
752  }
753 
756  Handle<Object> length,
757  Handle<FixedArrayBase> backing_store);
758 
759  virtual void SetCapacityAndLength(
760  Handle<JSArray> array,
761  int capacity,
762  int length) V8_FINAL V8_OVERRIDE {
763  ElementsAccessorSubclass::
764  SetFastElementsCapacityAndLength(array, capacity, length);
765  }
766 
769  int capacity,
770  int length) {
771  UNIMPLEMENTED();
772  }
773 
776  uint32_t key,
778 
780  uint32_t from_start,
782  ElementsKind from_kind,
783  uint32_t to_start,
784  int packed_size,
785  int copy_size) {
786  UNREACHABLE();
787  }
788 
789  virtual void CopyElements(
790  Handle<JSObject> from_holder,
791  uint32_t from_start,
792  ElementsKind from_kind,
794  uint32_t to_start,
795  int copy_size,
797  int packed_size = kPackedSizeNotKnown;
798  if (from.is_null()) {
799  from = handle(from_holder->elements());
800  }
801 
802  if (!from_holder.is_null()) {
803  bool is_packed = IsFastPackedElementsKind(from_kind) &&
804  from_holder->IsJSArray();
805  if (is_packed) {
806  packed_size =
807  Smi::cast(Handle<JSArray>::cast(from_holder)->length())->value();
808  if (copy_size >= 0 && packed_size > copy_size) {
809  packed_size = copy_size;
810  }
811  }
812  }
813  ElementsAccessorSubclass::CopyElementsImpl(
814  from, from_start, to, from_kind, to_start, packed_size, copy_size);
815  }
816 
818  Object* receiver,
819  JSObject* holder,
820  FixedArray* to,
822  int len0 = to->length();
823 #ifdef ENABLE_SLOW_ASSERTS
825  for (int i = 0; i < len0; i++) {
826  ASSERT(!to->get(i)->IsTheHole());
827  }
828  }
829 #endif
830  if (from == NULL) {
831  from = holder->elements();
832  }
833 
834  // Optimize if 'other' is empty.
835  // We cannot optimize if 'this' is empty, as other may have holes.
836  uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(from);
837  if (len1 == 0) return to;
838 
839  // Compute how many elements are not in other.
840  uint32_t extra = 0;
841  for (uint32_t y = 0; y < len1; y++) {
842  uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y);
843  if (ElementsAccessorSubclass::HasElementImpl(
844  receiver, holder, key, from)) {
845  MaybeObject* maybe_value =
846  ElementsAccessorSubclass::GetImpl(receiver, holder, key, from);
847  Object* value;
848  if (!maybe_value->To(&value)) return maybe_value;
849  ASSERT(!value->IsTheHole());
850  if (!HasKey(to, value)) {
851  extra++;
852  }
853  }
854  }
855 
856  if (extra == 0) return to;
857 
858  // Allocate the result
859  FixedArray* result;
860  MaybeObject* maybe_obj = from->GetHeap()->AllocateFixedArray(len0 + extra);
861  if (!maybe_obj->To(&result)) return maybe_obj;
862 
863  // Fill in the content
864  {
866  WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
867  for (int i = 0; i < len0; i++) {
868  Object* e = to->get(i);
869  ASSERT(e->IsString() || e->IsNumber());
870  result->set(i, e, mode);
871  }
872  }
873  // Fill in the extra values.
874  uint32_t index = 0;
875  for (uint32_t y = 0; y < len1; y++) {
876  uint32_t key =
877  ElementsAccessorSubclass::GetKeyForIndexImpl(from, y);
878  if (ElementsAccessorSubclass::HasElementImpl(
879  receiver, holder, key, from)) {
880  MaybeObject* maybe_value =
881  ElementsAccessorSubclass::GetImpl(receiver, holder, key, from);
882  Object* value;
883  if (!maybe_value->To(&value)) return maybe_value;
884  if (!value->IsTheHole() && !HasKey(to, value)) {
885  result->set(len0 + index, value);
886  index++;
887  }
888  }
889  }
890  ASSERT(extra == index);
891  return result;
892  }
893 
894  protected:
895  static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) {
896  return backing_store->length();
897  }
898 
899  virtual uint32_t GetCapacity(FixedArrayBase* backing_store)
901  return ElementsAccessorSubclass::GetCapacityImpl(backing_store);
902  }
903 
904  static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store,
905  uint32_t index) {
906  return index;
907  }
908 
909  virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
910  uint32_t index) V8_FINAL V8_OVERRIDE {
911  return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index);
912  }
913 
914  private:
915  DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase);
916 };
917 
918 
919 // Super class for all fast element arrays.
920 template<typename FastElementsAccessorSubclass,
921  typename KindTraits,
922  int ElementSize>
924  : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> {
925  public:
926  explicit FastElementsAccessor(const char* name)
927  : ElementsAccessorBase<FastElementsAccessorSubclass,
928  KindTraits>(name) {}
929  protected:
930  friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
932 
933  typedef typename KindTraits::BackingStore BackingStore;
934 
935  // Adjusts the length of the fast backing store or returns the new length or
936  // undefined in case conversion to a slow backing store should be performed.
938  Handle<FixedArrayBase> backing_store,
939  Handle<JSArray> array,
940  Handle<Object> length_object,
941  uint32_t length) {
942  Isolate* isolate = array->GetIsolate();
943  uint32_t old_capacity = backing_store->length();
944  Handle<Object> old_length(array->length(), isolate);
945  bool same_or_smaller_size = old_length->IsSmi() &&
946  static_cast<uint32_t>(Handle<Smi>::cast(old_length)->value()) >= length;
947  ElementsKind kind = array->GetElementsKind();
948 
949  if (!same_or_smaller_size && IsFastElementsKind(kind) &&
950  !IsFastHoleyElementsKind(kind)) {
951  kind = GetHoleyElementsKind(kind);
953  }
954 
955  // Check whether the backing store should be shrunk.
956  if (length <= old_capacity) {
957  if (array->HasFastSmiOrObjectElements()) {
958  backing_store = JSObject::EnsureWritableFastElements(array);
959  }
960  if (2 * length <= old_capacity) {
961  // If more than half the elements won't be used, trim the array.
962  if (length == 0) {
963  array->initialize_elements();
964  } else {
965  backing_store->set_length(length);
966  Address filler_start = backing_store->address() +
967  BackingStore::OffsetOfElementAt(length);
968  int filler_size = (old_capacity - length) * ElementSize;
969  array->GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
970  }
971  } else {
972  // Otherwise, fill the unused tail with holes.
973  int old_length = FastD2IChecked(array->length()->Number());
974  for (int i = length; i < old_length; i++) {
975  Handle<BackingStore>::cast(backing_store)->set_the_hole(i);
976  }
977  }
978  return length_object;
979  }
980 
981  // Check whether the backing store should be expanded.
982  uint32_t min = JSObject::NewElementsCapacity(old_capacity);
983  uint32_t new_capacity = length > min ? length : min;
984  if (!array->ShouldConvertToSlowElements(new_capacity)) {
985  FastElementsAccessorSubclass::
986  SetFastElementsCapacityAndLength(array, new_capacity, length);
987  array->ValidateElements();
988  return length_object;
989  }
990 
991  // Request conversion to slow elements.
992  return isolate->factory()->undefined_value();
993  }
994 
996  uint32_t key,
998  ASSERT(obj->HasFastSmiOrObjectElements() ||
999  obj->HasFastDoubleElements() ||
1000  obj->HasFastArgumentsElements());
1001  Isolate* isolate = obj->GetIsolate();
1002  Heap* heap = obj->GetHeap();
1003  Handle<FixedArrayBase> elements(obj->elements());
1004  if (*elements == heap->empty_fixed_array()) {
1005  return isolate->factory()->true_value();
1006  }
1007  Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements);
1008  bool is_sloppy_arguments_elements_map =
1009  backing_store->map() == heap->sloppy_arguments_elements_map();
1010  if (is_sloppy_arguments_elements_map) {
1011  backing_store = handle(
1012  BackingStore::cast(Handle<FixedArray>::cast(backing_store)->get(1)));
1013  }
1014  uint32_t length = static_cast<uint32_t>(
1015  obj->IsJSArray()
1016  ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value()
1017  : backing_store->length());
1018  if (key < length) {
1019  if (!is_sloppy_arguments_elements_map) {
1020  ElementsKind kind = KindTraits::Kind;
1021  if (IsFastPackedElementsKind(kind)) {
1023  }
1024  if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) {
1026  backing_store = Handle<BackingStore>::cast(writable);
1027  }
1028  }
1029  backing_store->set_the_hole(key);
1030  // If an old space backing store is larger than a certain size and
1031  // has too few used values, normalize it.
1032  // To avoid doing the check on every delete we require at least
1033  // one adjacent hole to the value being deleted.
1034  const int kMinLengthForSparsenessCheck = 64;
1035  if (backing_store->length() >= kMinLengthForSparsenessCheck &&
1036  !heap->InNewSpace(*backing_store) &&
1037  ((key > 0 && backing_store->is_the_hole(key - 1)) ||
1038  (key + 1 < length && backing_store->is_the_hole(key + 1)))) {
1039  int num_used = 0;
1040  for (int i = 0; i < backing_store->length(); ++i) {
1041  if (!backing_store->is_the_hole(i)) ++num_used;
1042  // Bail out early if more than 1/4 is used.
1043  if (4 * num_used > backing_store->length()) break;
1044  }
1045  if (4 * num_used <= backing_store->length()) {
1047  }
1048  }
1049  }
1050  return isolate->factory()->true_value();
1051  }
1052 
1055  uint32_t key,
1057  return DeleteCommon(obj, key, mode);
1058  }
1059 
1060  static bool HasElementImpl(
1061  Object* receiver,
1062  JSObject* holder,
1063  uint32_t key,
1064  FixedArrayBase* backing_store) {
1065  if (key >= static_cast<uint32_t>(backing_store->length())) {
1066  return false;
1067  }
1068  return !BackingStore::cast(backing_store)->is_the_hole(key);
1069  }
1070 
1071  static void ValidateContents(JSObject* holder, int length) {
1072 #if DEBUG
1073  FixedArrayBase* elements = holder->elements();
1074  Heap* heap = elements->GetHeap();
1075  Map* map = elements->map();
1076  ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) &&
1077  (map == heap->fixed_array_map() ||
1078  map == heap->fixed_cow_array_map())) ||
1079  (IsFastDoubleElementsKind(KindTraits::Kind) ==
1080  ((map == heap->fixed_array_map() && length == 0) ||
1081  map == heap->fixed_double_array_map())));
1082  for (int i = 0; i < length; i++) {
1083  BackingStore* backing_store = BackingStore::cast(elements);
1084  ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) ||
1085  static_cast<Object*>(backing_store->get(i))->IsSmi()) ||
1086  (IsFastHoleyElementsKind(KindTraits::Kind) ==
1087  backing_store->is_the_hole(i)));
1088  }
1089 #endif
1090  }
1091 };
1092 
1093 
1094 static inline ElementsKind ElementsKindForArray(FixedArrayBase* array) {
1095  switch (array->map()->instance_type()) {
1096  case FIXED_ARRAY_TYPE:
1097  if (array->IsDictionary()) {
1098  return DICTIONARY_ELEMENTS;
1099  } else {
1100  return FAST_HOLEY_ELEMENTS;
1101  }
1104 
1105 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1106  case EXTERNAL_##TYPE##_ARRAY_TYPE: \
1107  return EXTERNAL_##TYPE##_ELEMENTS; \
1108  case FIXED_##TYPE##_ARRAY_TYPE: \
1109  return TYPE##_ELEMENTS;
1110 
1112 #undef TYPED_ARRAY_CASE
1113 
1114  default:
1115  UNREACHABLE();
1116  }
1117  return FAST_HOLEY_ELEMENTS;
1118 }
1119 
1120 
1121 template<typename FastElementsAccessorSubclass,
1122  typename KindTraits>
1124  : public FastElementsAccessor<FastElementsAccessorSubclass,
1125  KindTraits,
1126  kPointerSize> {
1127  public:
1129  : FastElementsAccessor<FastElementsAccessorSubclass,
1130  KindTraits,
1131  kPointerSize>(name) {}
1132 
1134  uint32_t from_start,
1136  ElementsKind from_kind,
1137  uint32_t to_start,
1138  int packed_size,
1139  int copy_size) {
1140  ElementsKind to_kind = KindTraits::Kind;
1141  switch (from_kind) {
1142  case FAST_SMI_ELEMENTS:
1144  case FAST_ELEMENTS:
1145  case FAST_HOLEY_ELEMENTS:
1146  CopyObjectToObjectElements(
1147  from, from_kind, from_start, to, to_kind, to_start, copy_size);
1148  break;
1149  case FAST_DOUBLE_ELEMENTS:
1151  CopyDoubleToObjectElements(
1152  from, from_start, to, to_kind, to_start, copy_size);
1153  break;
1154  case DICTIONARY_ELEMENTS:
1155  CopyDictionaryToObjectElements(
1156  from, from_start, to, to_kind, to_start, copy_size);
1157  break;
1159  // TODO(verwaest): This is a temporary hack to support extending
1160  // SLOPPY_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength.
1161  // This case should be UNREACHABLE().
1162  Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(from);
1163  Handle<FixedArrayBase> arguments(
1164  FixedArrayBase::cast(parameter_map->get(1)));
1165  ElementsKind from_kind = ElementsKindForArray(*arguments);
1166  CopyElementsImpl(arguments, from_start, to, from_kind,
1167  to_start, packed_size, copy_size);
1168  break;
1169  }
1170 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1171  case EXTERNAL_##TYPE##_ELEMENTS: \
1172  case TYPE##_ELEMENTS: \
1173  UNREACHABLE();
1175 #undef TYPED_ARRAY_CASE
1176  }
1177  }
1178 
1179 
1182  uint32_t capacity,
1183  uint32_t length) {
1184  JSObject::SetFastElementsCapacitySmiMode set_capacity_mode =
1185  obj->HasFastSmiElements()
1189  obj, capacity, length, set_capacity_mode);
1190  }
1191 };
1192 
1193 
1196  FastPackedSmiElementsAccessor,
1197  ElementsKindTraits<FAST_SMI_ELEMENTS> > {
1198  public:
1199  explicit FastPackedSmiElementsAccessor(const char* name)
1203 };
1204 
1205 
1208  FastHoleySmiElementsAccessor,
1209  ElementsKindTraits<FAST_HOLEY_SMI_ELEMENTS> > {
1210  public:
1211  explicit FastHoleySmiElementsAccessor(const char* name)
1215 };
1216 
1217 
1220  FastPackedObjectElementsAccessor,
1221  ElementsKindTraits<FAST_ELEMENTS> > {
1222  public:
1226  ElementsKindTraits<FAST_ELEMENTS> >(name) {}
1227 };
1228 
1229 
1232  FastHoleyObjectElementsAccessor,
1233  ElementsKindTraits<FAST_HOLEY_ELEMENTS> > {
1234  public:
1239 };
1240 
1241 
1242 template<typename FastElementsAccessorSubclass,
1243  typename KindTraits>
1245  : public FastElementsAccessor<FastElementsAccessorSubclass,
1246  KindTraits,
1247  kDoubleSize> {
1248  public:
1249  explicit FastDoubleElementsAccessor(const char* name)
1250  : FastElementsAccessor<FastElementsAccessorSubclass,
1251  KindTraits,
1252  kDoubleSize>(name) {}
1253 
1255  uint32_t capacity,
1256  uint32_t length) {
1257  JSObject::SetFastDoubleElementsCapacityAndLength(obj, capacity, length);
1258  }
1259 
1260  protected:
1262  uint32_t from_start,
1264  ElementsKind from_kind,
1265  uint32_t to_start,
1266  int packed_size,
1267  int copy_size) {
1268  switch (from_kind) {
1269  case FAST_SMI_ELEMENTS:
1270  CopyPackedSmiToDoubleElements(
1271  from, from_start, to, to_start, packed_size, copy_size);
1272  break;
1274  CopySmiToDoubleElements(from, from_start, to, to_start, copy_size);
1275  break;
1276  case FAST_DOUBLE_ELEMENTS:
1278  CopyDoubleToDoubleElements(from, from_start, to, to_start, copy_size);
1279  break;
1280  case FAST_ELEMENTS:
1281  case FAST_HOLEY_ELEMENTS:
1282  CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size);
1283  break;
1284  case DICTIONARY_ELEMENTS:
1285  CopyDictionaryToDoubleElements(
1286  from, from_start, to, to_start, copy_size);
1287  break;
1289  UNREACHABLE();
1290 
1291 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1292  case EXTERNAL_##TYPE##_ELEMENTS: \
1293  case TYPE##_ELEMENTS: \
1294  UNREACHABLE();
1296 #undef TYPED_ARRAY_CASE
1297  }
1298  }
1299 };
1300 
1301 
1303  : public FastDoubleElementsAccessor<
1304  FastPackedDoubleElementsAccessor,
1305  ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > {
1306  public:
1307  friend class ElementsAccessorBase<FastPackedDoubleElementsAccessor,
1311  FastPackedDoubleElementsAccessor,
1313 };
1314 
1315 
1317  : public FastDoubleElementsAccessor<
1318  FastHoleyDoubleElementsAccessor,
1319  ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> > {
1320  public:
1321  friend class ElementsAccessorBase<
1322  FastHoleyDoubleElementsAccessor,
1326  FastHoleyDoubleElementsAccessor,
1328 };
1329 
1330 
1331 // Super class for all external element arrays.
1332 template<ElementsKind Kind>
1334  : public ElementsAccessorBase<TypedElementsAccessor<Kind>,
1335  ElementsKindTraits<Kind> > {
1336  public:
1337  explicit TypedElementsAccessor(const char* name)
1339  ElementsKindTraits<Kind> >(name) {}
1340 
1341  protected:
1344 
1345  friend class ElementsAccessorBase<AccessorClass,
1347 
1348  MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
1349  JSObject* obj,
1350  uint32_t key,
1351  FixedArrayBase* backing_store) {
1352  return
1353  key < AccessorClass::GetCapacityImpl(backing_store)
1354  ? BackingStore::cast(backing_store)->get(key)
1355  : backing_store->GetHeap()->undefined_value();
1356  }
1357 
1359  Object* receiver,
1360  JSObject* obj,
1361  uint32_t key,
1362  FixedArrayBase* backing_store) {
1363  return
1364  key < AccessorClass::GetCapacityImpl(backing_store)
1365  ? NONE : ABSENT;
1366  }
1367 
1369  Object* receiver,
1370  JSObject* obj,
1371  uint32_t key,
1372  FixedArrayBase* backing_store) {
1373  return
1374  key < AccessorClass::GetCapacityImpl(backing_store)
1375  ? FIELD : NONEXISTENT;
1376  }
1377 
1380  Handle<Object> length,
1381  Handle<FixedArrayBase> backing_store) {
1382  // External arrays do not support changing their length.
1383  UNREACHABLE();
1384  return obj;
1385  }
1386 
1389  uint32_t key,
1391  // External arrays always ignore deletes.
1392  return obj->GetIsolate()->factory()->true_value();
1393  }
1394 
1395  static bool HasElementImpl(Object* receiver,
1396  JSObject* holder,
1397  uint32_t key,
1398  FixedArrayBase* backing_store) {
1399  uint32_t capacity =
1400  AccessorClass::GetCapacityImpl(backing_store);
1401  return key < capacity;
1402  }
1403 };
1404 
1405 
1406 
1407 #define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \
1408  typedef TypedElementsAccessor<EXTERNAL_##TYPE##_ELEMENTS> \
1409  External##Type##ElementsAccessor;
1410 
1412 #undef EXTERNAL_ELEMENTS_ACCESSOR
1413 
1414 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \
1415  typedef TypedElementsAccessor<TYPE##_ELEMENTS > \
1416  Fixed##Type##ElementsAccessor;
1417 
1419 #undef FIXED_ELEMENTS_ACCESSOR
1420 
1421 
1422 
1424  : public ElementsAccessorBase<DictionaryElementsAccessor,
1425  ElementsKindTraits<DICTIONARY_ELEMENTS> > {
1426  public:
1427  explicit DictionaryElementsAccessor(const char* name)
1430 
1431  // Adjusts the length of the dictionary backing store and returns the new
1432  // length according to ES5 section 15.4.5.2 behavior.
1434  FixedArrayBase* store,
1435  JSArray* array,
1436  Object* length_object,
1437  uint32_t length) {
1439  Heap* heap = array->GetHeap();
1440  int capacity = dict->Capacity();
1441  uint32_t new_length = length;
1442  uint32_t old_length = static_cast<uint32_t>(array->length()->Number());
1443  if (new_length < old_length) {
1444  // Find last non-deletable element in range of elements to be
1445  // deleted and adjust range accordingly.
1446  for (int i = 0; i < capacity; i++) {
1447  Object* key = dict->KeyAt(i);
1448  if (key->IsNumber()) {
1449  uint32_t number = static_cast<uint32_t>(key->Number());
1450  if (new_length <= number && number < old_length) {
1451  PropertyDetails details = dict->DetailsAt(i);
1452  if (details.IsDontDelete()) new_length = number + 1;
1453  }
1454  }
1455  }
1456  if (new_length != length) {
1457  MaybeObject* maybe_object = heap->NumberFromUint32(new_length);
1458  if (!maybe_object->To(&length_object)) return maybe_object;
1459  }
1460  }
1461 
1462  if (new_length == 0) {
1463  // If the length of a slow array is reset to zero, we clear
1464  // the array and flush backing storage. This has the added
1465  // benefit that the array returns to fast mode.
1466  Object* obj;
1467  MaybeObject* maybe_obj = array->ResetElements();
1468  if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1469  } else {
1470  // Remove elements that should be deleted.
1471  int removed_entries = 0;
1472  Object* the_hole_value = heap->the_hole_value();
1473  for (int i = 0; i < capacity; i++) {
1474  Object* key = dict->KeyAt(i);
1475  if (key->IsNumber()) {
1476  uint32_t number = static_cast<uint32_t>(key->Number());
1477  if (new_length <= number && number < old_length) {
1478  dict->SetEntry(i, the_hole_value, the_hole_value);
1479  removed_entries++;
1480  }
1481  }
1482  }
1483 
1484  // Update the number of elements.
1485  dict->ElementsRemoved(removed_entries);
1486  }
1487  return length_object;
1488  }
1489 
1490  // TODO(ishell): Temporary wrapper until handlified.
1492  Handle<FixedArrayBase> store,
1493  Handle<JSArray> array,
1494  Handle<Object> length_object,
1495  uint32_t length) {
1496  CALL_HEAP_FUNCTION(array->GetIsolate(),
1498  *store, *array, *length_object, length),
1499  Object);
1500  }
1501 
1502  MUST_USE_RESULT static MaybeObject* DeleteCommon(
1503  JSObject* obj,
1504  uint32_t key,
1506  Isolate* isolate = obj->GetIsolate();
1507  Heap* heap = isolate->heap();
1508  FixedArray* backing_store = FixedArray::cast(obj->elements());
1509  bool is_arguments =
1511  if (is_arguments) {
1512  backing_store = FixedArray::cast(backing_store->get(1));
1513  }
1514  SeededNumberDictionary* dictionary =
1515  SeededNumberDictionary::cast(backing_store);
1516  int entry = dictionary->FindEntry(key);
1517  if (entry != SeededNumberDictionary::kNotFound) {
1518  Object* result = dictionary->DeleteProperty(entry, mode);
1519  if (result == heap->false_value()) {
1520  if (mode == JSObject::STRICT_DELETION) {
1521  // Deleting a non-configurable property in strict mode.
1522  HandleScope scope(isolate);
1523  Handle<Object> holder(obj, isolate);
1524  Handle<Object> name = isolate->factory()->NewNumberFromUint(key);
1525  Handle<Object> args[2] = { name, holder };
1526  Handle<Object> error =
1527  isolate->factory()->NewTypeError("strict_delete_property",
1528  HandleVector(args, 2));
1529  return isolate->Throw(*error);
1530  }
1531  return heap->false_value();
1532  }
1533  MaybeObject* maybe_elements = dictionary->Shrink(key);
1534  FixedArray* new_elements = NULL;
1535  if (!maybe_elements->To(&new_elements)) {
1536  return maybe_elements;
1537  }
1538  if (is_arguments) {
1539  FixedArray::cast(obj->elements())->set(1, new_elements);
1540  } else {
1541  obj->set_elements(new_elements);
1542  }
1543  }
1544  return heap->true_value();
1545  }
1546 
1547  // TODO(ishell): Temporary wrapper until handlified.
1550  uint32_t key,
1552  CALL_HEAP_FUNCTION(obj->GetIsolate(),
1553  DeleteCommon(*obj, key, mode),
1554  Object);
1555  }
1556 
1558  uint32_t from_start,
1560  ElementsKind from_kind,
1561  uint32_t to_start,
1562  int packed_size,
1563  int copy_size) {
1564  UNREACHABLE();
1565  }
1566 
1567 
1568  protected:
1571 
1574  uint32_t key,
1576  return DeleteCommon(obj, key, mode);
1577  }
1578 
1579  MUST_USE_RESULT static MaybeObject* GetImpl(
1580  Object* receiver,
1581  JSObject* obj,
1582  uint32_t key,
1583  FixedArrayBase* store) {
1584  SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
1585  int entry = backing_store->FindEntry(key);
1586  if (entry != SeededNumberDictionary::kNotFound) {
1587  Object* element = backing_store->ValueAt(entry);
1588  PropertyDetails details = backing_store->DetailsAt(entry);
1589  if (details.type() == CALLBACKS) {
1590  return obj->GetElementWithCallback(receiver,
1591  element,
1592  key,
1593  obj);
1594  } else {
1595  return element;
1596  }
1597  }
1598  return obj->GetHeap()->the_hole_value();
1599  }
1600 
1602  Object* receiver,
1603  JSObject* obj,
1604  uint32_t key,
1605  FixedArrayBase* backing_store) {
1606  SeededNumberDictionary* dictionary =
1607  SeededNumberDictionary::cast(backing_store);
1608  int entry = dictionary->FindEntry(key);
1609  if (entry != SeededNumberDictionary::kNotFound) {
1610  return dictionary->DetailsAt(entry).attributes();
1611  }
1612  return ABSENT;
1613  }
1614 
1616  Object* receiver,
1617  JSObject* obj,
1618  uint32_t key,
1619  FixedArrayBase* store) {
1620  SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
1621  int entry = backing_store->FindEntry(key);
1622  if (entry != SeededNumberDictionary::kNotFound) {
1623  return backing_store->DetailsAt(entry).type();
1624  }
1625  return NONEXISTENT;
1626  }
1627 
1629  Object* receiver,
1630  JSObject* obj,
1631  uint32_t key,
1632  FixedArrayBase* store) {
1633  SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
1634  int entry = backing_store->FindEntry(key);
1635  if (entry != SeededNumberDictionary::kNotFound &&
1636  backing_store->DetailsAt(entry).type() == CALLBACKS &&
1637  backing_store->ValueAt(entry)->IsAccessorPair()) {
1638  return AccessorPair::cast(backing_store->ValueAt(entry));
1639  }
1640  return NULL;
1641  }
1642 
1643  static bool HasElementImpl(Object* receiver,
1644  JSObject* holder,
1645  uint32_t key,
1646  FixedArrayBase* backing_store) {
1647  return SeededNumberDictionary::cast(backing_store)->FindEntry(key) !=
1649  }
1650 
1651  static uint32_t GetKeyForIndexImpl(FixedArrayBase* store,
1652  uint32_t index) {
1654  Object* key = dict->KeyAt(index);
1655  return Smi::cast(key)->value();
1656  }
1657 };
1658 
1659 
1661  SloppyArgumentsElementsAccessor,
1662  ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> > {
1663  public:
1668  protected:
1669  friend class ElementsAccessorBase<
1672 
1673  MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver,
1674  JSObject* obj,
1675  uint32_t key,
1676  FixedArrayBase* parameters) {
1677  FixedArray* parameter_map = FixedArray::cast(parameters);
1678  Object* probe = GetParameterMapArg(obj, parameter_map, key);
1679  if (!probe->IsTheHole()) {
1680  Context* context = Context::cast(parameter_map->get(0));
1681  int context_index = Smi::cast(probe)->value();
1682  ASSERT(!context->get(context_index)->IsTheHole());
1683  return context->get(context_index);
1684  } else {
1685  // Object is not mapped, defer to the arguments.
1686  FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1687  MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get(
1688  receiver, obj, key, arguments);
1689  Object* result;
1690  if (!maybe_result->ToObject(&result)) return maybe_result;
1691  // Elements of the arguments object in slow mode might be slow aliases.
1692  if (result->IsAliasedArgumentsEntry()) {
1694  Context* context = Context::cast(parameter_map->get(0));
1695  int context_index = entry->aliased_context_slot();
1696  ASSERT(!context->get(context_index)->IsTheHole());
1697  return context->get(context_index);
1698  } else {
1699  return result;
1700  }
1701  }
1702  }
1703 
1705  Object* receiver,
1706  JSObject* obj,
1707  uint32_t key,
1708  FixedArrayBase* backing_store) {
1709  FixedArray* parameter_map = FixedArray::cast(backing_store);
1710  Object* probe = GetParameterMapArg(obj, parameter_map, key);
1711  if (!probe->IsTheHole()) {
1712  return NONE;
1713  } else {
1714  // If not aliased, check the arguments.
1715  FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1716  return ElementsAccessor::ForArray(arguments)->GetAttributes(
1717  receiver, obj, key, arguments);
1718  }
1719  }
1720 
1722  Object* receiver,
1723  JSObject* obj,
1724  uint32_t key,
1725  FixedArrayBase* parameters) {
1726  FixedArray* parameter_map = FixedArray::cast(parameters);
1727  Object* probe = GetParameterMapArg(obj, parameter_map, key);
1728  if (!probe->IsTheHole()) {
1729  return FIELD;
1730  } else {
1731  // If not aliased, check the arguments.
1732  FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1733  return ElementsAccessor::ForArray(arguments)->GetType(
1734  receiver, obj, key, arguments);
1735  }
1736  }
1737 
1739  Object* receiver,
1740  JSObject* obj,
1741  uint32_t key,
1742  FixedArrayBase* parameters) {
1743  FixedArray* parameter_map = FixedArray::cast(parameters);
1744  Object* probe = GetParameterMapArg(obj, parameter_map, key);
1745  if (!probe->IsTheHole()) {
1746  return NULL;
1747  } else {
1748  // If not aliased, check the arguments.
1749  FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1750  return ElementsAccessor::ForArray(arguments)->GetAccessorPair(
1751  receiver, obj, key, arguments);
1752  }
1753  }
1754 
1757  Handle<Object> length,
1758  Handle<FixedArrayBase> parameter_map) {
1759  // TODO(mstarzinger): This was never implemented but will be used once we
1760  // correctly implement [[DefineOwnProperty]] on arrays.
1761  UNIMPLEMENTED();
1762  return obj;
1763  }
1764 
1767  uint32_t key,
1769  Isolate* isolate = obj->GetIsolate();
1770  Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
1771  Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key);
1772  if (!probe->IsTheHole()) {
1773  // TODO(kmillikin): We could check if this was the last aliased
1774  // parameter, and revert to normal elements in that case. That
1775  // would enable GC of the context.
1776  parameter_map->set_the_hole(key + 2);
1777  } else {
1778  Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
1779  if (arguments->IsDictionary()) {
1781  } else {
1782  // It's difficult to access the version of DeleteCommon that is declared
1783  // in the templatized super class, call the concrete implementation in
1784  // the class for the most generalized ElementsKind subclass.
1786  }
1787  }
1788  return isolate->factory()->true_value();
1789  }
1790 
1792  uint32_t from_start,
1794  ElementsKind from_kind,
1795  uint32_t to_start,
1796  int packed_size,
1797  int copy_size) {
1798  UNREACHABLE();
1799  }
1800 
1801  static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) {
1802  FixedArray* parameter_map = FixedArray::cast(backing_store);
1803  FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1804  return Max(static_cast<uint32_t>(parameter_map->length() - 2),
1805  ForArray(arguments)->GetCapacity(arguments));
1806  }
1807 
1808  static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict,
1809  uint32_t index) {
1810  return index;
1811  }
1812 
1813  static bool HasElementImpl(Object* receiver,
1814  JSObject* holder,
1815  uint32_t key,
1816  FixedArrayBase* parameters) {
1817  FixedArray* parameter_map = FixedArray::cast(parameters);
1818  Object* probe = GetParameterMapArg(holder, parameter_map, key);
1819  if (!probe->IsTheHole()) {
1820  return true;
1821  } else {
1822  FixedArrayBase* arguments =
1823  FixedArrayBase::cast(FixedArray::cast(parameter_map)->get(1));
1824  ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
1825  return !accessor->Get(receiver, holder, key, arguments)->IsTheHole();
1826  }
1827  }
1828 
1829  private:
1830  // TODO(ishell): remove when all usages are handlified.
1831  static Object* GetParameterMapArg(JSObject* holder,
1832  FixedArray* parameter_map,
1833  uint32_t key) {
1834  uint32_t length = holder->IsJSArray()
1835  ? Smi::cast(JSArray::cast(holder)->length())->value()
1836  : parameter_map->length();
1837  return key < (length - 2)
1838  ? parameter_map->get(key + 2)
1839  : parameter_map->GetHeap()->the_hole_value();
1840  }
1841 
1842  static Handle<Object> GetParameterMapArg(Handle<JSObject> holder,
1843  Handle<FixedArray> parameter_map,
1844  uint32_t key) {
1845  Isolate* isolate = holder->GetIsolate();
1846  uint32_t length = holder->IsJSArray()
1847  ? Smi::cast(Handle<JSArray>::cast(holder)->length())->value()
1848  : parameter_map->length();
1849  return key < (length - 2)
1850  ? handle(parameter_map->get(key + 2), isolate)
1851  : Handle<Object>::cast(isolate->factory()->the_hole_value());
1852  }
1853 };
1854 
1855 
1857  return elements_accessors_[ElementsKindForArray(array)];
1858 }
1859 
1860 
1862  static ElementsAccessor* accessor_array[] = {
1863 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind),
1865 #undef ACCESSOR_ARRAY
1866  };
1867 
1868  STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) ==
1870 
1871  elements_accessors_ = accessor_array;
1872 }
1873 
1874 
1876 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind];
1878 #undef ACCESSOR_DELETE
1879  elements_accessors_ = NULL;
1880 }
1881 
1882 
1883 template <typename ElementsAccessorSubclass, typename ElementsKindTraits>
1884 MUST_USE_RESULT Handle<Object> ElementsAccessorBase<ElementsAccessorSubclass,
1886  SetLengthImpl(Handle<JSObject> obj,
1887  Handle<Object> length,
1888  Handle<FixedArrayBase> backing_store) {
1889  Isolate* isolate = obj->GetIsolate();
1891 
1892  // Fast case: The new length fits into a Smi.
1893  Handle<Object> smi_length = Object::ToSmi(isolate, length);
1894 
1895  if (!smi_length.is_null() && smi_length->IsSmi()) {
1896  const int value = Handle<Smi>::cast(smi_length)->value();
1897  if (value >= 0) {
1898  Handle<Object> new_length = ElementsAccessorSubclass::
1899  SetLengthWithoutNormalize(backing_store, array, smi_length, value);
1900  RETURN_IF_EMPTY_HANDLE_VALUE(isolate, new_length, new_length);
1901 
1902  // even though the proposed length was a smi, new_length could
1903  // still be a heap number because SetLengthWithoutNormalize doesn't
1904  // allow the array length property to drop below the index of
1905  // non-deletable elements.
1906  ASSERT(new_length->IsSmi() || new_length->IsHeapNumber() ||
1907  new_length->IsUndefined());
1908  if (new_length->IsSmi()) {
1909  array->set_length(*Handle<Smi>::cast(new_length));
1910  return array;
1911  } else if (new_length->IsHeapNumber()) {
1912  array->set_length(*new_length);
1913  return array;
1914  }
1915  } else {
1916  return ThrowArrayLengthRangeError(isolate);
1917  }
1918  }
1919 
1920  // Slow case: The new length does not fit into a Smi or conversion
1921  // to slow elements is needed for other reasons.
1922  if (length->IsNumber()) {
1923  uint32_t value;
1924  if (length->ToArrayIndex(&value)) {
1925  Handle<SeededNumberDictionary> dictionary =
1927  RETURN_IF_EMPTY_HANDLE_VALUE(isolate, dictionary, dictionary);
1928 
1930  SetLengthWithoutNormalize(dictionary, array, length, value);
1931  RETURN_IF_EMPTY_HANDLE_VALUE(isolate, new_length, new_length);
1932 
1933  ASSERT(new_length->IsNumber());
1934  array->set_length(*new_length);
1935  return array;
1936  } else {
1937  return ThrowArrayLengthRangeError(isolate);
1938  }
1939  }
1940 
1941  // Fall-back case: The new length is not a number so make the array
1942  // size one and set only element to length.
1943  Handle<FixedArray> new_backing_store = isolate->factory()->NewFixedArray(1);
1944  new_backing_store->set(0, *length);
1945  JSArray::SetContent(array, new_backing_store);
1946  return array;
1947 }
1948 
1949 
1951  Arguments* args) {
1952  // Optimize the case where there is one argument and the argument is a
1953  // small smi.
1954  if (args->length() == 1) {
1955  Handle<Object> obj = args->at<Object>(0);
1956  if (obj->IsSmi()) {
1957  int len = Handle<Smi>::cast(obj)->value();
1958  if (len > 0 && len < JSObject::kInitialMaxFastElementArray) {
1959  ElementsKind elements_kind = array->GetElementsKind();
1960  JSArray::Initialize(array, len, len);
1961 
1962  if (!IsFastHoleyElementsKind(elements_kind)) {
1963  elements_kind = GetHoleyElementsKind(elements_kind);
1964  JSObject::TransitionElementsKind(array, elements_kind);
1965  }
1966  return array;
1967  } else if (len == 0) {
1969  return array;
1970  }
1971  }
1972 
1973  // Take the argument as the length.
1974  JSArray::Initialize(array, 0);
1975 
1976  return JSArray::SetElementsLength(array, obj);
1977  }
1978 
1979  // Optimize the case where there are no parameters passed.
1980  if (args->length() == 0) {
1982  return array;
1983  }
1984 
1985  Factory* factory = array->GetIsolate()->factory();
1986 
1987  // Set length and elements on the array.
1988  int number_of_elements = args->length();
1990  array, args, 0, number_of_elements, ALLOW_CONVERTED_DOUBLE_ELEMENTS);
1991 
1992  // Allocate an appropriately typed elements array.
1993  ElementsKind elements_kind = array->GetElementsKind();
1995  if (IsFastDoubleElementsKind(elements_kind)) {
1997  factory->NewFixedDoubleArray(number_of_elements));
1998  } else {
2000  factory->NewFixedArrayWithHoles(number_of_elements));
2001  }
2002 
2003  // Fill in the content
2004  switch (array->GetElementsKind()) {
2006  case FAST_SMI_ELEMENTS: {
2008  for (int index = 0; index < number_of_elements; index++) {
2009  smi_elms->set(index, (*args)[index], SKIP_WRITE_BARRIER);
2010  }
2011  break;
2012  }
2013  case FAST_HOLEY_ELEMENTS:
2014  case FAST_ELEMENTS: {
2015  DisallowHeapAllocation no_gc;
2016  WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
2017  Handle<FixedArray> object_elms = Handle<FixedArray>::cast(elms);
2018  for (int index = 0; index < number_of_elements; index++) {
2019  object_elms->set(index, (*args)[index], mode);
2020  }
2021  break;
2022  }
2024  case FAST_DOUBLE_ELEMENTS: {
2025  Handle<FixedDoubleArray> double_elms =
2027  for (int index = 0; index < number_of_elements; index++) {
2028  double_elms->set(index, (*args)[index]->Number());
2029  }
2030  break;
2031  }
2032  default:
2033  UNREACHABLE();
2034  break;
2035  }
2036 
2037  array->set_elements(*elms);
2038  array->set_length(Smi::FromInt(number_of_elements));
2039  return array;
2040 }
2041 
2042 } } // namespace v8::internal
static MUST_USE_RESULT PropertyType GetTypeImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *parameters)
Definition: elements.cc:1721
byte * Address
Definition: globals.h:186
virtual MUST_USE_RESULT AccessorPair * GetAccessorPair(Object *receiver, JSObject *holder, uint32_t key, FixedArrayBase *backing_store=NULL)=0
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
virtual MUST_USE_RESULT PropertyAttributes GetAttributes(Object *receiver, JSObject *holder, uint32_t key, FixedArrayBase *backing_store) V8_FINAL V8_OVERRIDE
Definition: elements.cc:680
Object * KeyAt(int entry)
Definition: objects.h:3697
static void EnsureCanContainElements(Handle< JSObject > object, Object **elements, uint32_t count, EnsureElementsMode mode)
Definition: objects-inl.h:1603
virtual MUST_USE_RESULT MaybeObject * Get(Object *receiver, JSObject *holder, uint32_t key, FixedArrayBase *backing_store) V8_FINAL V8_OVERRIDE
Definition: elements.cc:648
FastDoubleElementsAccessor(const char *name)
Definition: elements.cc:1249
#define ACCESSOR_DELETE(Class, Kind, Store)
#define ACCESSOR_ARRAY(Class, Kind, Store)
bool IsExternalArrayElementsKind(ElementsKind kind)
static MUST_USE_RESULT MaybeObject * SetLengthWithoutNormalize(FixedArrayBase *store, JSArray *array, Object *length_object, uint32_t length)
Definition: elements.cc:1433
static void SetFastElementsCapacityAndLength(Handle< JSObject > obj, uint32_t capacity, uint32_t length)
Definition: elements.cc:1180
virtual MUST_USE_RESULT PropertyAttributes GetAttributes(Object *receiver, JSObject *holder, uint32_t key, FixedArrayBase *backing_store=NULL)=0
static MUST_USE_RESULT MaybeObject * GetImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *parameters)
Definition: elements.cc:1673
void set(int index, Object *value)
Definition: objects-inl.h:2147
virtual MUST_USE_RESULT Handle< Object > Delete(Handle< JSObject > obj, uint32_t key, JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE
Definition: elements.cc:1387
static Handle< FixedArray > SetFastElementsCapacityAndLength(Handle< JSObject > object, int capacity, int length, SetFastElementsCapacitySmiMode smi_mode)
Definition: objects.cc:11143
static MUST_USE_RESULT PropertyAttributes GetAttributesImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *backing_store)
Definition: elements.cc:1358
void PrintF(const char *format,...)
Definition: v8utils.cc:40
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf map
Definition: flags.cc:350
bool InNewSpace(Object *object)
Definition: heap-inl.h:307
TypedElementsAccessor(const char *name)
Definition: elements.cc:1337
static String * cast(Object *obj)
ElementsTraitsParam::BackingStore BackingStore
Definition: elements.cc:584
virtual MUST_USE_RESULT AccessorPair * GetAccessorPair(Object *receiver, JSObject *holder, uint32_t key, FixedArrayBase *backing_store) V8_FINAL V8_OVERRIDE
Definition: elements.cc:727
Handle< FixedArray > NewFixedArrayWithHoles(int size, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:62
static Smi * FromInt(int value)
Definition: objects-inl.h:1209
bool IsFastObjectElementsKind(ElementsKind kind)
MUST_USE_RESULT MaybeObject * ToSmi()
Definition: objects-inl.h:1042
static void CopyElementsImpl(Handle< FixedArrayBase > from, uint32_t from_start, Handle< FixedArrayBase > to, ElementsKind from_kind, uint32_t to_start, int packed_size, int copy_size)
Definition: elements.cc:779
ElementsKindTraits< Kind >::BackingStore BackingStore
Definition: elements.cc:1342
static MUST_USE_RESULT PropertyType GetTypeImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *backing_store)
Definition: elements.cc:715
virtual MUST_USE_RESULT Handle< Object > Get(Handle< Object > receiver, Handle< JSObject > holder, uint32_t key, Handle< FixedArrayBase > backing_store=Handle< FixedArrayBase >::null())=0
static Handle< T > cast(Handle< S > that)
Definition: handles.h:75
T Max(T a, T b)
Definition: utils.h:227
static AccessorPair * cast(Object *obj)
static uint32_t GetCapacityImpl(FixedArrayBase *backing_store)
Definition: elements.cc:1801
kSerializedDataOffset Object
Definition: objects-inl.h:5016
static uint32_t GetKeyForIndexImpl(FixedArrayBase *backing_store, uint32_t index)
Definition: elements.cc:904
int int32_t
Definition: unicode.cc:47
static MUST_USE_RESULT MaybeObject * GetImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *backing_store)
Definition: elements.cc:1348
WriteBarrierMode GetWriteBarrierMode(const DisallowHeapAllocation &promise)
Definition: objects-inl.h:2350
static AliasedArgumentsEntry * cast(Object *obj)
void CheckArrayAbuse(JSObject *obj, const char *op, uint32_t key, bool allow_appending)
Definition: elements.cc:520
DictionaryElementsAccessor(const char *name)
Definition: elements.cc:1427
Handle< Object > ArrayConstructInitializeElements(Handle< JSArray > array, Arguments *args)
Definition: elements.cc:1950
#define ASSERT(condition)
Definition: checks.h:329
virtual MUST_USE_RESULT Handle< Object > Delete(Handle< JSObject > obj, uint32_t key, JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE
Definition: elements.cc:1765
static bool HasElementImpl(Object *receiver, JSObject *holder, uint32_t key, FixedArrayBase *backing_store)
Definition: elements.cc:1395
KindTraits::BackingStore BackingStore
Definition: elements.cc:933
static Context * cast(Object *context)
Definition: contexts.h:244
#define ELEMENTS_LIST(V)
Definition: elements.cc:86
ElementsTraitsParam ElementsTraits
Definition: elements.cc:583
FastElementsAccessor(const char *name)
Definition: elements.cc:926
const bool FLAG_enable_slow_asserts
Definition: checks.h:307
Factory * factory()
Definition: isolate.h:995
bool IsFastElementsKind(ElementsKind kind)
MUST_USE_RESULT MaybeObject * EnsureWritableFastElements()
Definition: objects-inl.h:6124
PropertyAttributes
virtual void Validate(JSObject *holder) V8_FINAL V8_OVERRIDE
Definition: elements.cc:612
virtual void CopyElements(Handle< JSObject > from_holder, uint32_t from_start, ElementsKind from_kind, Handle< FixedArrayBase > to, uint32_t to_start, int copy_size, Handle< FixedArrayBase > from) V8_FINAL V8_OVERRIDE
Definition: elements.cc:789
static MUST_USE_RESULT Handle< Object > SetLengthImpl(Handle< JSObject > obj, Handle< Object > length, Handle< FixedArrayBase > backing_store)
Definition: elements.cc:1886
#define RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, value)
Definition: isolate.h:137
static Smi * cast(Object *object)
bool Equals(String *other)
Definition: objects-inl.h:2969
static MUST_USE_RESULT MaybeObject * DeleteCommon(JSObject *obj, uint32_t key, JSReceiver::DeleteMode mode)
Definition: elements.cc:1502
virtual MUST_USE_RESULT PropertyType GetType(Object *receiver, JSObject *holder, uint32_t key, FixedArrayBase *backing_store=NULL)=0
static uint32_t GetKeyForIndexImpl(FixedArrayBase *store, uint32_t index)
Definition: elements.cc:1651
static void TransitionElementsKind(Handle< JSObject > object, ElementsKind to_kind)
Definition: objects.cc:12779
static const int kCopyToEnd
Definition: elements.h:142
Object * ValueAt(int entry)
Definition: objects.h:3930
static void SetContent(Handle< JSArray > array, Handle< FixedArrayBase > storage)
Definition: objects-inl.h:6641
static MUST_USE_RESULT MaybeObject * GetImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *backing_store)
Definition: elements.cc:671
HANDLE HANDLE LPSTACKFRAME64 StackFrame
#define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size)
Definition: elements.cc:1407
#define UNREACHABLE()
Definition: checks.h:52
static MUST_USE_RESULT PropertyAttributes GetAttributesImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *backing_store)
Definition: elements.cc:692
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_string(expose_natives_as
static void ValidateImpl(JSObject *holder)
Definition: elements.cc:593
static uint32_t GetKeyForIndexImpl(FixedArrayBase *dict, uint32_t index)
Definition: elements.cc:1808
static SeededNumberDictionary * cast(Object *obj)
Definition: objects.h:4104
static MUST_USE_RESULT MaybeObject * GetImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *store)
Definition: elements.cc:1579
static bool HasElementImpl(Object *receiver, JSObject *holder, uint32_t key, FixedArrayBase *backing_store)
Definition: elements.cc:1643
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
#define MUST_USE_RESULT
Definition: globals.h:381
bool IsFastPackedElementsKind(ElementsKind kind)
const int kDoubleSize
Definition: globals.h:266
static void ValidateContents(JSObject *holder, int length)
Definition: elements.cc:1071
int FastD2IChecked(double x)
Definition: conversions.h:63
#define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE)
Definition: heap-inl.h:679
virtual MUST_USE_RESULT MaybeObject * AddElementsToFixedArray(Object *receiver, JSObject *holder, FixedArray *to, FixedArrayBase *from) V8_FINAL V8_OVERRIDE
Definition: elements.cc:817
bool ToArrayIndex(uint32_t *index)
Definition: objects-inl.h:2072
MUST_USE_RESULT MaybeObject * ResetElements()
Definition: objects-inl.h:1755
ElementsKind GetElementsKind()
Definition: objects-inl.h:5999
static void PrintTop(Isolate *isolate, FILE *file, bool print_args, bool print_line_number)
Definition: frames.cc:804
const int kPointerSize
Definition: globals.h:268
Handle< Object > NewTypeError(const char *message, Vector< Handle< Object > > args)
Definition: factory.cc:1039
unsigned int FastD2UI(double x)
static MUST_USE_RESULT Handle< Object > SetLengthImpl(Handle< JSObject > obj, Handle< Object > length, Handle< FixedArrayBase > backing_store)
Definition: elements.cc:1378
static void InitializeOncePerProcess()
Definition: elements.cc:1861
Handle< FixedDoubleArray > NewFixedDoubleArray(int size, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:80
Handle< FixedArray > NewFixedArray(int size, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:53
static void CopyElementsImpl(Handle< FixedArrayBase > from, uint32_t from_start, Handle< FixedArrayBase > to, ElementsKind from_kind, uint32_t to_start, int packed_size, int copy_size)
Definition: elements.cc:1791
#define ELEMENTS_TRAITS(Class, KindParam, Store)
Definition: elements.cc:136
bool IsFastSmiElementsKind(ElementsKind kind)
void CopyWords(T *dst, const T *src, size_t num_words)
Definition: v8utils.h:130
#define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size)
Definition: elements.cc:1414
static ElementsAccessor * ForArray(FixedArrayBase *array)
Definition: elements.cc:1856
static Handle< Object > SetLengthWithoutNormalize(Handle< FixedArrayBase > backing_store, Handle< JSArray > array, Handle< Object > length_object, uint32_t length)
Definition: elements.cc:937
static void SetFastElementsCapacityAndLength(Handle< JSObject > obj, uint32_t capacity, uint32_t length)
Definition: elements.cc:1254
MUST_USE_RESULT MaybeObject * Shrink(Key key)
Definition: objects.cc:15206
static bool HasElementImpl(Object *receiver, JSObject *holder, uint32_t key, FixedArrayBase *backing_store)
Definition: elements.cc:616
virtual Handle< Object > Delete(Handle< JSObject > obj, uint32_t key, JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE
Definition: elements.cc:1053
Failure * Throw(Object *exception, MessageLocation *location=NULL)
Definition: isolate.cc:923
virtual uint32_t GetCapacity(FixedArrayBase *backing_store) V8_FINAL V8_OVERRIDE
Definition: elements.cc:899
static JSArray * cast(Object *obj)
virtual MUST_USE_RESULT Handle< Object > Get(Handle< Object > receiver, Handle< JSObject > holder, uint32_t key, Handle< FixedArrayBase > backing_store) V8_FINAL V8_OVERRIDE
Definition: elements.cc:636
virtual ElementsKind kind() const V8_FINAL V8_OVERRIDE
Definition: elements.cc:586
bool IsFastSmiOrObjectElementsKind(ElementsKind kind)
static Handle< Object > DeleteCommon(Handle< JSObject > obj, uint32_t key, JSReceiver::DeleteMode mode)
Definition: elements.cc:995
const int kElementsKindCount
Definition: elements-kind.h:89
static const int kHeaderSize
Definition: objects.h:3016
static void Initialize(Handle< JSArray > array, int capacity, int length=0)
Definition: objects.cc:11244
static void CopyElementsImpl(Handle< FixedArrayBase > from, uint32_t from_start, Handle< FixedArrayBase > to, ElementsKind from_kind, uint32_t to_start, int packed_size, int copy_size)
Definition: elements.cc:1557
static const int kCopyToEndAndInitializeToHole
Definition: elements.h:147
int32_t DoubleToInt32(double x)
static Handle< Object > SetElementsLength(Handle< JSArray > array, Handle< Object > length)
Definition: objects.cc:11330
#define V8_OVERRIDE
Definition: v8config.h:402
Handle< T > handle(T *t, Isolate *isolate)
Definition: handles.h:103
static void CopyElementsImpl(Handle< FixedArrayBase > from, uint32_t from_start, Handle< FixedArrayBase > to, ElementsKind from_kind, uint32_t to_start, int packed_size, int copy_size)
Definition: elements.cc:1261
MUST_USE_RESULT MaybeObject * NumberFromUint32(uint32_t value, PretenureFlag pretenure=NOT_TENURED)
Definition: heap-inl.h:280
#define UNIMPLEMENTED()
Definition: checks.h:50
PropertyDetails DetailsAt(int entry)
Definition: objects.h:3940
Object * DeleteProperty(int entry, JSObject::DeleteMode mode)
Definition: objects.cc:15191
virtual uint32_t GetKeyForIndex(FixedArrayBase *backing_store, uint32_t index) V8_FINAL V8_OVERRIDE
Definition: elements.cc:909
static Handle< SeededNumberDictionary > NormalizeElements(Handle< JSObject > object)
Definition: objects.cc:4704
#define TYPED_ARRAYS(V)
Definition: objects.h:4663
void MemsetPointer(T **dest, U *value, int counter)
Definition: v8utils.h:198
static uint32_t GetCapacityImpl(FixedArrayBase *backing_store)
Definition: elements.cc:895
MUST_USE_RESULT MaybeObject * AllocateFixedArray(int length, PretenureFlag pretenure=NOT_TENURED)
Definition: heap.cc:5297
static MUST_USE_RESULT PropertyAttributes GetAttributesImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *backing_store)
Definition: elements.cc:1601
PerThreadAssertScopeDebugOnly< HEAP_ALLOCATION_ASSERT, false > DisallowHeapAllocation
Definition: assert-scope.h:214
virtual MUST_USE_RESULT Handle< Object > Delete(Handle< JSObject > obj, uint32_t key, JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE
Definition: elements.cc:1572
static FixedArray * cast(Object *obj)
static void SetFastDoubleElementsCapacityAndLength(Handle< JSObject > object, int capacity, int length)
Definition: objects.cc:11205
virtual MUST_USE_RESULT PropertyType GetType(Object *receiver, JSObject *holder, uint32_t key, FixedArrayBase *backing_store) V8_FINAL V8_OVERRIDE
Definition: elements.cc:703
static bool HasElementImpl(Object *receiver, JSObject *holder, uint32_t key, FixedArrayBase *backing_store)
Definition: elements.cc:1060
static MUST_USE_RESULT PropertyType GetTypeImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *backing_store)
Definition: elements.cc:1368
static MUST_USE_RESULT Handle< Object > DeleteCommon(Handle< JSObject > obj, uint32_t key, JSReceiver::DeleteMode mode)
Definition: elements.cc:1548
double FastI2D(int x)
Definition: conversions.h:81
TypedElementsAccessor< Kind > AccessorClass
Definition: elements.cc:1343
void SetEntry(int entry, Object *key, Object *value)
Definition: objects-inl.h:6465
Object * get(int index)
Definition: objects-inl.h:2127
static const int kPreallocatedArrayElements
Definition: objects.h:10073
bool IsFastHoleyElementsKind(ElementsKind kind)
static MUST_USE_RESULT AccessorPair * GetAccessorPairImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *parameters)
Definition: elements.cc:1738
HeapObject * obj
static MUST_USE_RESULT PropertyAttributes GetAttributesImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *backing_store)
Definition: elements.cc:1704
static bool HasElementImpl(Object *receiver, JSObject *holder, uint32_t key, FixedArrayBase *parameters)
Definition: elements.cc:1813
static MUST_USE_RESULT Handle< Object > SetLengthImpl(Handle< JSObject > obj, Handle< Object > length, Handle< FixedArrayBase > parameter_map)
Definition: elements.cc:1755
static MUST_USE_RESULT AccessorPair * GetAccessorPairImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *backing_store)
Definition: elements.cc:739
Definition: objects.h:8475
Vector< Handle< Object > > HandleVector(v8::internal::Handle< T > *elms, int length)
Definition: v8utils.h:118
int aliased_context_slot()
virtual uint32_t GetCapacity(FixedArrayBase *backing_store)=0
T Min(T a, T b)
Definition: utils.h:234
static void SetFastElementsCapacityAndLength(Handle< JSObject > obj, int capacity, int length)
Definition: elements.cc:767
virtual void SetCapacityAndLength(Handle< JSArray > array, int capacity, int length) V8_FINAL V8_OVERRIDE
Definition: elements.cc:759
static void CopyElementsImpl(Handle< FixedArrayBase > from, uint32_t from_start, Handle< FixedArrayBase > to, ElementsKind from_kind, uint32_t to_start, int packed_size, int copy_size)
Definition: elements.cc:1133
static int NewElementsCapacity(int old_capacity)
Definition: objects.h:2467
static FixedArrayBase * cast(Object *object)
Definition: objects-inl.h:2121
ElementsAccessorBase(const char *name)
Definition: elements.cc:580
static const int kInitialMaxFastElementArray
Definition: objects.h:2744
static MUST_USE_RESULT Handle< Object > SetLengthWithoutNormalize(Handle< FixedArrayBase > store, Handle< JSArray > array, Handle< Object > length_object, uint32_t length)
Definition: elements.cc:1491
virtual MUST_USE_RESULT Handle< Object > SetLength(Handle< JSArray > array, Handle< Object > length) V8_FINAL V8_OVERRIDE
Definition: elements.cc:747
virtual MUST_USE_RESULT Handle< Object > Delete(Handle< JSObject > obj, uint32_t key, JSReceiver::DeleteMode mode) V8_OVERRIDE=0
Handle< Object > NewNumberFromUint(uint32_t value, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:1014
static MUST_USE_RESULT PropertyType GetTypeImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *store)
Definition: elements.cc:1615
static void ValidateContents(JSObject *holder, int length)
Definition: elements.cc:590
ElementsKind GetHoleyElementsKind(ElementsKind packed_kind)
const char * name() const
Definition: elements.h:47
void ElementsRemoved(int n)
Definition: objects.h:3680
virtual bool HasElement(Object *receiver, JSObject *holder, uint32_t key, FixedArrayBase *backing_store) V8_FINAL V8_OVERRIDE
Definition: elements.cc:624
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)
bool IsFastDoubleElementsKind(ElementsKind kind)
static MUST_USE_RESULT AccessorPair * GetAccessorPairImpl(Object *receiver, JSObject *obj, uint32_t key, FixedArrayBase *store)
Definition: elements.cc:1628