elements.cc revision 5d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0b
15d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Redistribution and use in source and binary forms, with or without 369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// modification, are permitted provided that the following conditions are 469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// met: 569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// * Redistributions of source code must retain the above copyright 769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// notice, this list of conditions and the following disclaimer. 869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// * Redistributions in binary form must reproduce the above 969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// copyright notice, this list of conditions and the following 1069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// disclaimer in the documentation and/or other materials provided 1169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// with the distribution. 1269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// * Neither the name of Google Inc. nor the names of its 1369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// contributors may be used to endorse or promote products derived 1469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// from this software without specific prior written permission. 1569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 1669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 2869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#include "v8.h" 2969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#include "objects.h" 3169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#include "elements.h" 3269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#include "utils.h" 3369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 34592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 35592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// Each concrete ElementsAccessor can handle exactly one ElementsKind, 36592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// several abstract ElementsAccessor classes are used to allow sharing 37592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// common code. 38592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// 39592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// Inheritance hierarchy: 40592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - ElementsAccessorBase (abstract) 41592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - FastElementsAccessor (abstract) 42592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - FastObjectElementsAccessor 43592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - FastDoubleElementsAccessor 44592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - ExternalElementsAccessor (abstract) 45592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - ExternalByteElementsAccessor 46592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - ExternalUnsignedByteElementsAccessor 47592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - ExternalShortElementsAccessor 48592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - ExternalUnsignedShortElementsAccessor 49592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - ExternalIntElementsAccessor 50592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - ExternalUnsignedIntElementsAccessor 51592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - ExternalFloatElementsAccessor 52592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - ExternalDoubleElementsAccessor 53592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - PixelElementsAccessor 54592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - DictionaryElementsAccessor 55592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// - NonStrictArgumentsElementsAccessor 56592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 57592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 5869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochnamespace v8 { 5969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochnamespace internal { 6069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 6169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 625d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch// First argument in list is the accessor class, the second argument is the 635d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch// accessor ElementsKind, and the third is the backing store class. Use the 645d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch// fast element handler for smi-only arrays. The implementation is currently 655d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch// identical. Note that the order must match that of the ElementsKind enum for 665d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch// the |accessor_array[]| below to work. 675d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#define ELEMENTS_LIST(V) \ 685d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(FastObjectElementsAccessor, FAST_SMI_ONLY_ELEMENTS, FixedArray) \ 695d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(FastObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \ 705d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(FastDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, FixedDoubleArray) \ 715d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, \ 725d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch SeededNumberDictionary) \ 735d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(NonStrictArgumentsElementsAccessor, NON_STRICT_ARGUMENTS_ELEMENTS, \ 745d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray) \ 755d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(ExternalByteElementsAccessor, EXTERNAL_BYTE_ELEMENTS, \ 765d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ExternalByteArray) \ 775d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(ExternalUnsignedByteElementsAccessor, \ 785d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_UNSIGNED_BYTE_ELEMENTS, ExternalUnsignedByteArray) \ 795d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(ExternalShortElementsAccessor, EXTERNAL_SHORT_ELEMENTS, \ 805d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ExternalShortArray) \ 815d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(ExternalUnsignedShortElementsAccessor, \ 825d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_UNSIGNED_SHORT_ELEMENTS, ExternalUnsignedShortArray) \ 835d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(ExternalIntElementsAccessor, EXTERNAL_INT_ELEMENTS, \ 845d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ExternalIntArray) \ 855d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(ExternalUnsignedIntElementsAccessor, \ 865d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_UNSIGNED_INT_ELEMENTS, ExternalUnsignedIntArray) \ 875d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(ExternalFloatElementsAccessor, \ 885d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_FLOAT_ELEMENTS, ExternalFloatArray) \ 895d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(ExternalDoubleElementsAccessor, \ 905d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_DOUBLE_ELEMENTS, ExternalDoubleArray) \ 915d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch V(PixelElementsAccessor, EXTERNAL_PIXEL_ELEMENTS, ExternalPixelArray) 925d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 935d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 945d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdochtemplate<ElementsKind Kind> class ElementsKindTraits { 955d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 965d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch typedef FixedArrayBase BackingStore; 975d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch}; 985d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 995d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#define ELEMENTS_TRAITS(Class, KindParam, Store) \ 1005d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdochtemplate<> class ElementsKindTraits<KindParam> { \ 1015d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: \ 1025d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static const ElementsKind Kind = KindParam; \ 1035d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch typedef Store BackingStore; \ 1045d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch}; 1055d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen MurdochELEMENTS_LIST(ELEMENTS_TRAITS) 1065d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#undef ELEMENTS_TRAITS 1075d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 1085d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 10969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochElementsAccessor** ElementsAccessor::elements_accessors_; 11069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 112592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdochstatic bool HasKey(FixedArray* array, Object* key) { 11369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int len0 = array->length(); 11469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (int i = 0; i < len0; i++) { 11569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* element = array->get(i); 11669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (element->IsSmi() && element == key) return true; 11769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (element->IsString() && 11869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch key->IsString() && String::cast(element)->Equals(String::cast(key))) { 11969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return true; 12069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 12169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 12269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return false; 12369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 12469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 12569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 126592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdochstatic Failure* ThrowArrayLengthRangeError(Heap* heap) { 127592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch HandleScope scope(heap->isolate()); 128592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return heap->isolate()->Throw( 129592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch *heap->isolate()->factory()->NewRangeError("invalid_array_length", 130592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch HandleVector<Object>(NULL, 0))); 131592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 132592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 133592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 1345d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdochvoid CopyObjectToObjectElements(FixedArray* from, 1355d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKind from_kind, 1365d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t from_start, 1375d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray* to, 1385d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKind to_kind, 1395d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t to_start, 1405d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int raw_copy_size) { 1415d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(to->map() != HEAP->fixed_cow_array_map()); 1425d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS); 1435d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); 1445d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int copy_size = raw_copy_size; 1455d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (raw_copy_size < 0) { 1465d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 1475d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 1485d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch copy_size = Min(from->length() - from_start, 1495d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->length() - to_start); 1505d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#ifdef DEBUG 1515d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already 1525d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // marked with the hole. 1535d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 1545d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch for (int i = to_start + copy_size; i < to->length(); ++i) { 1555d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(to->get(i)->IsTheHole()); 1565d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 1575d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 1585d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#endif 1595d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 1605d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 1615d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch (copy_size + static_cast<int>(from_start)) <= from->length()); 1625d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (copy_size == 0) return; 1635d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Address to_address = to->address() + FixedArray::kHeaderSize; 1645d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Address from_address = from->address() + FixedArray::kHeaderSize; 1655d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch CopyWords(reinterpret_cast<Object**>(to_address) + to_start, 1665d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch reinterpret_cast<Object**>(from_address) + from_start, 1675d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch copy_size); 1685d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS) { 1695d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Heap* heap = from->GetHeap(); 1705d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (!heap->InNewSpace(to)) { 1715d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch heap->RecordWrites(to->address(), 1725d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->OffsetOfElementAt(to_start), 1735d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch copy_size); 1745d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 1755d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch heap->incremental_marking()->RecordWrites(to); 1765d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 1775d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch} 1785d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 1795d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 1805d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdochstatic void CopyDictionaryToObjectElements(SeededNumberDictionary* from, 1815d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t from_start, 1825d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray* to, 1835d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKind to_kind, 1845d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t to_start, 1855d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int raw_copy_size) { 1865d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int copy_size = raw_copy_size; 1875d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Heap* heap = from->GetHeap(); 1885d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (raw_copy_size < 0) { 1895d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 1905d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 1915d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch copy_size = from->max_number_key() + 1 - from_start; 1925d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#ifdef DEBUG 1935d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already 1945d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // marked with the hole. 1955d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 1965d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch for (int i = to_start + copy_size; i < to->length(); ++i) { 1975d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(to->get(i)->IsTheHole()); 1985d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 1995d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2005d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#endif 2015d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2025d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT((copy_size + static_cast<int>(to_start)) <= to->length()); 2035d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(to != from); 2045d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); 2055d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (copy_size == 0) return; 2065d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch for (int i = 0; i < copy_size; i++) { 2075d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int entry = from->FindEntry(i + from_start); 2085d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (entry != SeededNumberDictionary::kNotFound) { 2095d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Object* value = from->ValueAt(entry); 2105d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(!value->IsTheHole()); 2115d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->set(i + to_start, value, SKIP_WRITE_BARRIER); 2125d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } else { 2135d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->set_the_hole(i + to_start); 2145d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2155d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2165d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (to_kind == FAST_ELEMENTS) { 2175d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (!heap->InNewSpace(to)) { 2185d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch heap->RecordWrites(to->address(), 2195d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->OffsetOfElementAt(to_start), 2205d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch copy_size); 2215d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2225d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch heap->incremental_marking()->RecordWrites(to); 2235d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2245d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch} 2255d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 2265d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 2275d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen MurdochMUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( 2285d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedDoubleArray* from, 2295d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t from_start, 2305d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray* to, 2315d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKind to_kind, 2325d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t to_start, 2335d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int raw_copy_size) { 2345d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); 2355d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int copy_size = raw_copy_size; 2365d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (raw_copy_size < 0) { 2375d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 2385d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 2395d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch copy_size = Min(from->length() - from_start, 2405d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->length() - to_start); 2415d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#ifdef DEBUG 2425d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already 2435d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // marked with the hole. 2445d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 2455d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch for (int i = to_start + copy_size; i < to->length(); ++i) { 2465d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(to->get(i)->IsTheHole()); 2475d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2485d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2495d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#endif 2505d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2515d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 2525d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch (copy_size + static_cast<int>(from_start)) <= from->length()); 2535d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (copy_size == 0) return from; 2545d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch for (int i = 0; i < copy_size; ++i) { 2555d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (to_kind == FAST_SMI_ONLY_ELEMENTS) { 2565d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch UNIMPLEMENTED(); 2575d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return Failure::Exception(); 2585d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } else { 2595d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch MaybeObject* maybe_value = from->get(i + from_start); 2605d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Object* value; 2615d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(to_kind == FAST_ELEMENTS); 2625d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // Because FAST_DOUBLE_ELEMENTS -> FAST_ELEMENT allocate HeapObjects 2635d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // iteratively, the allocate must succeed within a single GC cycle, 2645d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // otherwise the retry after the GC will also fail. In order to ensure 2655d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // that no GC is triggered, allocate HeapNumbers from old space if they 2665d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // can't be taken from new space. 2675d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (!maybe_value->ToObject(&value)) { 2685d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory()); 2695d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Heap* heap = from->GetHeap(); 2705d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch MaybeObject* maybe_value_object = 2715d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch heap->AllocateHeapNumber(from->get_scalar(i + from_start), 2725d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch TENURED); 2735d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (!maybe_value_object->ToObject(&value)) return maybe_value_object; 2745d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2755d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->set(i + to_start, value, UPDATE_WRITE_BARRIER); 2765d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2775d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2785d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return to; 2795d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch} 2805d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 2815d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 2825d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdochstatic void CopyDoubleToDoubleElements(FixedDoubleArray* from, 2835d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t from_start, 2845d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedDoubleArray* to, 2855d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t to_start, 2865d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int raw_copy_size) { 2875d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int copy_size = raw_copy_size; 2885d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (raw_copy_size < 0) { 2895d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 2905d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 2915d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch copy_size = Min(from->length() - from_start, 2925d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->length() - to_start); 2935d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 2945d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch for (int i = to_start + copy_size; i < to->length(); ++i) { 2955d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->set_the_hole(i); 2965d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2975d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2985d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 2995d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 3005d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch (copy_size + static_cast<int>(from_start)) <= from->length()); 3015d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (copy_size == 0) return; 3025d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Address to_address = to->address() + FixedDoubleArray::kHeaderSize; 3035d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Address from_address = from->address() + FixedDoubleArray::kHeaderSize; 3045d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to_address += kDoubleSize * to_start; 3055d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch from_address += kDoubleSize * from_start; 3065d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int words_per_double = (kDoubleSize / kPointerSize); 3075d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch CopyWords(reinterpret_cast<Object**>(to_address), 3085d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch reinterpret_cast<Object**>(from_address), 3095d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch words_per_double * copy_size); 3105d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch} 3115d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 3125d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 3135d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdochstatic void CopyObjectToDoubleElements(FixedArray* from, 3145d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t from_start, 3155d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedDoubleArray* to, 3165d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t to_start, 3175d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int raw_copy_size) { 3185d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int copy_size = raw_copy_size; 3195d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (raw_copy_size < 0) { 3205d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 3215d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 3225d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch copy_size = from->length() - from_start; 3235d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 3245d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch for (int i = to_start + copy_size; i < to->length(); ++i) { 3255d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->set_the_hole(i); 3265d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 3275d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 3285d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 3295d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 3305d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch (copy_size + static_cast<int>(from_start)) <= from->length()); 3315d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (copy_size == 0) return; 3325d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch for (int i = 0; i < copy_size; i++) { 3335d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Object* hole_or_object = from->get(i + from_start); 3345d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (hole_or_object->IsTheHole()) { 3355d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->set_the_hole(i + to_start); 3365d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } else { 3375d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->set(i + to_start, hole_or_object->Number()); 3385d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 3395d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 3405d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch} 3415d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 3425d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 3435d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdochstatic void CopyDictionaryToDoubleElements(SeededNumberDictionary* from, 3445d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t from_start, 3455d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedDoubleArray* to, 3465d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t to_start, 3475d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int raw_copy_size) { 3485d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int copy_size = raw_copy_size; 3495d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (copy_size < 0) { 3505d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(copy_size == ElementsAccessor::kCopyToEnd || 3515d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 3525d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch copy_size = from->max_number_key() + 1 - from_start; 3535d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 3545d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch for (int i = to_start + copy_size; i < to->length(); ++i) { 3555d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->set_the_hole(i); 3565d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 3575d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 3585d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 3595d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(copy_size + static_cast<int>(to_start) <= to->length()); 3605d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (copy_size == 0) return; 3615d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch for (int i = 0; i < copy_size; i++) { 3625d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int entry = from->FindEntry(i + from_start); 3635d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (entry != SeededNumberDictionary::kNotFound) { 3645d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->set(i + to_start, from->ValueAt(entry)->Number()); 3655d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } else { 3665d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to->set_the_hole(i + to_start); 3675d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 3685d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 3695d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch} 3705d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 3715d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 37269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Base class for element handler implementations. Contains the 37369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// the common logic for objects with different ElementsKinds. 37469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Subclasses must specialize method for which the element 37569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// implementation differs from the base class implementation. 37669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 37769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// This class is intended to be used in the following way: 37869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 37969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// class SomeElementsAccessor : 38069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// public ElementsAccessorBase<SomeElementsAccessor, 38169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// BackingStoreClass> { 38269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// ... 38369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// } 38469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 38569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// This is an example of the Curiously Recurring Template Pattern (see 38669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use 38769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// CRTP to guarantee aggressive compile time optimizations (i.e. inlining and 38869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// specialization of SomeElementsAccessor methods). 3895d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdochtemplate <typename ElementsAccessorSubclass, 3905d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch typename ElementsTraitsParam> 39169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ElementsAccessorBase : public ElementsAccessor { 39269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch protected: 3935d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit ElementsAccessorBase(const char* name) 3945d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ElementsAccessor(name) { } 3955d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 3965d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch typedef ElementsTraitsParam ElementsTraits; 3975d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch typedef typename ElementsTraitsParam::BackingStore BackingStore; 3985d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 3995d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch virtual ElementsKind kind() const { return ElementsTraits::Kind; } 4005d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 4015d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static bool HasElementImpl(Object* receiver, 4025d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch JSObject* holder, 4035d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t key, 4045d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch BackingStore* backing_store) { 4055d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch MaybeObject* element = 4065d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsAccessorSubclass::GetImpl(receiver, holder, key, backing_store); 4075d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return !element->IsTheHole(); 4085d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 4095d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 4105d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch virtual bool HasElement(Object* receiver, 4115d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch JSObject* holder, 4125d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t key, 4135d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArrayBase* backing_store) { 4145d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (backing_store == NULL) { 4155d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch backing_store = holder->elements(); 4165d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 4175d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return ElementsAccessorSubclass::HasElementImpl( 4185d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch receiver, holder, key, BackingStore::cast(backing_store)); 4195d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 4205d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 4215d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch virtual MaybeObject* Get(Object* receiver, 4225d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch JSObject* holder, 42369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key, 4245d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArrayBase* backing_store) { 4255d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (backing_store == NULL) { 4265d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch backing_store = holder->elements(); 4275d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 428592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return ElementsAccessorSubclass::GetImpl( 4295d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch receiver, holder, key, BackingStore::cast(backing_store)); 43069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 43169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 4325d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static MaybeObject* GetImpl(Object* receiver, 433592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch JSObject* obj, 4345d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t key, 4355d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch BackingStore* backing_store) { 436592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) 437592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch ? backing_store->get(key) 438592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch : backing_store->GetHeap()->the_hole_value(); 43969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 44069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 4415d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch virtual MaybeObject* SetLength(JSArray* array, 442592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch Object* length) { 443592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return ElementsAccessorSubclass::SetLengthImpl( 4445d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch array, length, BackingStore::cast(array->elements())); 445592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 446592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 4475d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static MaybeObject* SetLengthImpl(JSObject* obj, 4485d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Object* length, 4495d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch BackingStore* backing_store); 450592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 451c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch virtual MaybeObject* SetCapacityAndLength(JSArray* array, 452c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch int capacity, 453c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch int length) { 454c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch return ElementsAccessorSubclass::SetFastElementsCapacityAndLength( 455c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch array, 456c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch capacity, 457c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch length); 458c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch } 459c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 460c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 461c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch int capacity, 462c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch int length) { 463c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch UNIMPLEMENTED(); 464c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch return obj; 465c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch } 466c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 46769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual MaybeObject* Delete(JSObject* obj, 46869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key, 46969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) = 0; 47069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 4715d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 4725d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t from_start, 4735d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArrayBase* to, 4745d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKind to_kind, 4755d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t to_start, 4765d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int copy_size) { 4775d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch UNREACHABLE(); 4785d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return NULL; 4795d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 4805d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 4815d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch virtual MaybeObject* CopyElements(JSObject* from_holder, 4825d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t from_start, 4835d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArrayBase* to, 4845d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKind to_kind, 4855d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t to_start, 4865d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int copy_size, 4875d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArrayBase* from) { 4885d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (from == NULL) { 4895d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch from = from_holder->elements(); 4905d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 4915d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (from->length() == 0) { 4925d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return from; 4935d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 4945d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return ElementsAccessorSubclass::CopyElementsImpl( 4955d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch from, from_start, to, to_kind, to_start, copy_size); 4965d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 4975d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 4985d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch virtual MaybeObject* AddElementsToFixedArray(Object* receiver, 49969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSObject* holder, 5005d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray* to, 5015d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArrayBase* from) { 50269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int len0 = to->length(); 50369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef DEBUG 50469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (FLAG_enable_slow_asserts) { 50569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (int i = 0; i < len0; i++) { 50669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(!to->get(i)->IsTheHole()); 50769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 50869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 50969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif 5105d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (from == NULL) { 5115d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch from = holder->elements(); 5125d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 5135d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch BackingStore* backing_store = BackingStore::cast(from); 514592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store); 51569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 51669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Optimize if 'other' is empty. 51769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // We cannot optimize if 'this' is empty, as other may have holes. 51869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (len1 == 0) return to; 51969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 52069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Compute how many elements are not in other. 5215d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t extra = 0; 52269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (uint32_t y = 0; y < len1; y++) { 5235d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t key = 5245d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); 5255d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (ElementsAccessorSubclass::HasElementImpl( 5265d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch receiver, holder, key, backing_store)) { 52769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch MaybeObject* maybe_value = 5285d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsAccessorSubclass::GetImpl(receiver, holder, 5295d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch key, backing_store); 53069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* value; 53169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!maybe_value->ToObject(&value)) return maybe_value; 53269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(!value->IsTheHole()); 53369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!HasKey(to, value)) { 53469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch extra++; 53569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 53669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 53769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 53869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 53969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (extra == 0) return to; 54069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 54169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Allocate the result 54269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* result; 54369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch MaybeObject* maybe_obj = 54469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch backing_store->GetHeap()->AllocateFixedArray(len0 + extra); 54569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!maybe_obj->To<FixedArray>(&result)) return maybe_obj; 54669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 54769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Fill in the content 54869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { 54969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch AssertNoAllocation no_gc; 55069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 55169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (int i = 0; i < len0; i++) { 55269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* e = to->get(i); 55369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(e->IsString() || e->IsNumber()); 55469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch result->set(i, e, mode); 55569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 55669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 55769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Fill in the extra values. 5585d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t index = 0; 55969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (uint32_t y = 0; y < len1; y++) { 5605d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t key = 5615d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); 5625d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (ElementsAccessorSubclass::HasElementImpl( 5635d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch receiver, holder, key, backing_store)) { 56469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch MaybeObject* maybe_value = 5655d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsAccessorSubclass::GetImpl(receiver, holder, 5665d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch key, backing_store); 56769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* value; 56869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!maybe_value->ToObject(&value)) return maybe_value; 56969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!value->IsTheHole() && !HasKey(to, value)) { 57069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch result->set(len0 + index, value); 57169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch index++; 57269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 57369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 57469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 57569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(extra == index); 57669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return result; 57769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 57869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 57969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch protected: 5805d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static uint32_t GetCapacityImpl(BackingStore* backing_store) { 58169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return backing_store->length(); 58269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 58369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 58469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { 585592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return ElementsAccessorSubclass::GetCapacityImpl( 5865d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch BackingStore::cast(backing_store)); 58769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 58869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 5895d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static uint32_t GetKeyForIndexImpl(BackingStore* backing_store, 590592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t index) { 59169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return index; 59269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 59369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 59469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, 5955d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t index) { 596592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return ElementsAccessorSubclass::GetKeyForIndexImpl( 5975d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch BackingStore::cast(backing_store), index); 59869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 59969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 60069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch private: 60169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 60269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 60369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 60469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 605592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch// Super class for all fast element arrays. 606592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdochtemplate<typename FastElementsAccessorSubclass, 6075d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch typename KindTraits, 608592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch int ElementSize> 60969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass FastElementsAccessor 6105d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { 6115d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 6125d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit FastElementsAccessor(const char* name) 6135d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ElementsAccessorBase<FastElementsAccessorSubclass, 6145d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch KindTraits>(name) {} 615592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch protected: 6165d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>; 6175d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 6185d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch typedef typename KindTraits::BackingStore BackingStore; 619592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 620592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // Adjusts the length of the fast backing store or returns the new length or 621592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // undefined in case conversion to a slow backing store should be performed. 622592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch static MaybeObject* SetLengthWithoutNormalize(BackingStore* backing_store, 623592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch JSArray* array, 624592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch Object* length_object, 625592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t length) { 626592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t old_capacity = backing_store->length(); 627592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 628592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // Check whether the backing store should be shrunk. 629592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (length <= old_capacity) { 630592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (array->HasFastTypeElements()) { 631592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch MaybeObject* maybe_obj = array->EnsureWritableFastElements(); 632592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (!maybe_obj->To(&backing_store)) return maybe_obj; 633592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 634592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (2 * length <= old_capacity) { 635592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // If more than half the elements won't be used, trim the array. 636592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (length == 0) { 637592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch array->initialize_elements(); 638592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } else { 639592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch backing_store->set_length(length); 640592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch Address filler_start = backing_store->address() + 641592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch BackingStore::OffsetOfElementAt(length); 642592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch int filler_size = (old_capacity - length) * ElementSize; 643592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch array->GetHeap()->CreateFillerObjectAt(filler_start, filler_size); 644592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 645592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } else { 646592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // Otherwise, fill the unused tail with holes. 647592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch int old_length = FastD2I(array->length()->Number()); 648592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch for (int i = length; i < old_length; i++) { 649592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch backing_store->set_the_hole(i); 650592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 651592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 652592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return length_object; 653592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 654592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 655592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // Check whether the backing store should be expanded. 656592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t min = JSObject::NewElementsCapacity(old_capacity); 657592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t new_capacity = length > min ? length : min; 658592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (!array->ShouldConvertToSlowElements(new_capacity)) { 659592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch MaybeObject* result = FastElementsAccessorSubclass:: 660592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch SetFastElementsCapacityAndLength(array, new_capacity, length); 661592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (result->IsFailure()) return result; 662592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return length_object; 663592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 664592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 665592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // Request conversion to slow elements. 666592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return array->GetHeap()->undefined_value(); 667592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 668592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}; 669592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 670592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 671592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdochclass FastObjectElementsAccessor 672592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch : public FastElementsAccessor<FastObjectElementsAccessor, 6735d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<FAST_ELEMENTS>, 674592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch kPointerSize> { 67569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch public: 6765d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit FastObjectElementsAccessor(const char* name) 6775d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : FastElementsAccessor<FastObjectElementsAccessor, 6785d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<FAST_ELEMENTS>, 6795d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch kPointerSize>(name) {} 6805d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 68169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static MaybeObject* DeleteCommon(JSObject* obj, 68269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key) { 683592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch ASSERT(obj->HasFastElements() || 684592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch obj->HasFastSmiOnlyElements() || 685592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch obj->HasFastArgumentsElements()); 68669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Heap* heap = obj->GetHeap(); 68769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* backing_store = FixedArray::cast(obj->elements()); 68869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (backing_store->map() == heap->non_strict_arguments_elements_map()) { 68969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch backing_store = FixedArray::cast(backing_store->get(1)); 69069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 69169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* writable; 69269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch MaybeObject* maybe = obj->EnsureWritableFastElements(); 69369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!maybe->ToObject(&writable)) return maybe; 69469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch backing_store = FixedArray::cast(writable); 69569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 69669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t length = static_cast<uint32_t>( 69769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch obj->IsJSArray() 69869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ? Smi::cast(JSArray::cast(obj)->length())->value() 69969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : backing_store->length()); 70069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (key < length) { 70169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch backing_store->set_the_hole(key); 70269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // If an old space backing store is larger than a certain size and 70369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // has too few used values, normalize it. 70469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // To avoid doing the check on every delete we require at least 70569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // one adjacent hole to the value being deleted. 70669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* hole = heap->the_hole_value(); 70769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const int kMinLengthForSparsenessCheck = 64; 70869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (backing_store->length() >= kMinLengthForSparsenessCheck && 70969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch !heap->InNewSpace(backing_store) && 71069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ((key > 0 && backing_store->get(key - 1) == hole) || 71169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch (key + 1 < length && backing_store->get(key + 1) == hole))) { 71269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int num_used = 0; 71369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (int i = 0; i < backing_store->length(); ++i) { 71469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (backing_store->get(i) != hole) ++num_used; 71569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Bail out early if more than 1/4 is used. 71669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (4 * num_used > backing_store->length()) break; 71769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 71869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (4 * num_used <= backing_store->length()) { 71969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch MaybeObject* result = obj->NormalizeElements(); 72069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (result->IsFailure()) return result; 72169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 72269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 72369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 72469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return heap->true_value(); 72569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 72669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 7275d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 7285d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t from_start, 7295d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArrayBase* to, 7305d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKind to_kind, 7315d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t to_start, 7325d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int copy_size) { 7335d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch switch (to_kind) { 7345d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch case FAST_SMI_ONLY_ELEMENTS: 7355d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch case FAST_ELEMENTS: { 7365d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch CopyObjectToObjectElements( 7375d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray::cast(from), ElementsTraits::Kind, from_start, 7385d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray::cast(to), to_kind, to_start, copy_size); 7395d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return from; 7405d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 7415d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch case FAST_DOUBLE_ELEMENTS: 7425d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch CopyObjectToDoubleElements( 7435d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray::cast(from), from_start, 7445d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedDoubleArray::cast(to), to_start, copy_size); 7455d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return from; 7465d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch default: 7475d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch UNREACHABLE(); 7485d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 7495d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return to->GetHeap()->undefined_value(); 7505d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 7515d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 7525d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 753592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 754592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t capacity, 755592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t length) { 756592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch JSObject::SetFastElementsCapacityMode set_capacity_mode = 757592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch obj->HasFastSmiOnlyElements() 758592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch ? JSObject::kAllowSmiOnlyElements 759592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch : JSObject::kDontAllowSmiOnlyElements; 760592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return obj->SetFastElementsCapacityAndLength(capacity, 761592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch length, 762592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch set_capacity_mode); 763592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 764592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 765c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch protected: 766c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch friend class FastElementsAccessor<FastObjectElementsAccessor, 7675d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<FAST_ELEMENTS>, 768c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch kPointerSize>; 769c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 77069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual MaybeObject* Delete(JSObject* obj, 77169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key, 77269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) { 77369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return DeleteCommon(obj, key); 77469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 77569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 77669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 77769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 77869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass FastDoubleElementsAccessor 779592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch : public FastElementsAccessor<FastDoubleElementsAccessor, 7805d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<FAST_DOUBLE_ELEMENTS>, 781592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch kDoubleSize> { 7825d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 7835d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit FastDoubleElementsAccessor(const char* name) 7845d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : FastElementsAccessor<FastDoubleElementsAccessor, 7855d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<FAST_DOUBLE_ELEMENTS>, 7865d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch kDoubleSize>(name) {} 7875d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 788c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 789c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch uint32_t capacity, 790c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch uint32_t length) { 791c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch return obj->SetFastDoubleElementsCapacityAndLength(capacity, length); 792c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch } 793c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 79469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch protected: 79569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch friend class ElementsAccessorBase<FastDoubleElementsAccessor, 7965d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >; 797592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch friend class FastElementsAccessor<FastDoubleElementsAccessor, 7985d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<FAST_DOUBLE_ELEMENTS>, 799592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch kDoubleSize>; 800592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 8015d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 8025d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t from_start, 8035d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArrayBase* to, 8045d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKind to_kind, 8055d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t to_start, 8065d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int copy_size) { 8075d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch switch (to_kind) { 8085d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch case FAST_SMI_ONLY_ELEMENTS: 8095d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch case FAST_ELEMENTS: 8105d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return CopyDoubleToObjectElements( 8115d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedDoubleArray::cast(from), from_start, FixedArray::cast(to), 8125d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to_kind, to_start, copy_size); 8135d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch case FAST_DOUBLE_ELEMENTS: 8145d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch CopyDoubleToDoubleElements(FixedDoubleArray::cast(from), from_start, 8155d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedDoubleArray::cast(to), 8165d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to_start, copy_size); 8175d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return from; 8185d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch default: 8195d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch UNREACHABLE(); 8205d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 8215d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return to->GetHeap()->undefined_value(); 8225d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 8235d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 82469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual MaybeObject* Delete(JSObject* obj, 82569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key, 82669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) { 82769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int length = obj->IsJSArray() 82869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ? Smi::cast(JSArray::cast(obj)->length())->value() 82969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : FixedDoubleArray::cast(obj->elements())->length(); 83069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (key < static_cast<uint32_t>(length)) { 83169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedDoubleArray::cast(obj->elements())->set_the_hole(key); 83269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 83369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return obj->GetHeap()->true_value(); 83469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 83569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 8365d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static bool HasElementImpl(Object* receiver, 8375d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch JSObject* holder, 8385d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t key, 8395d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedDoubleArray* backing_store) { 8405d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return key < static_cast<uint32_t>(backing_store->length()) && 8415d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch !backing_store->is_the_hole(key); 84269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 84369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 84469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 84569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 84669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Super class for all external element arrays. 84769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochtemplate<typename ExternalElementsAccessorSubclass, 8485d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKind Kind> 84969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalElementsAccessor 85069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ElementsAccessorBase<ExternalElementsAccessorSubclass, 8515d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<Kind> > { 8525d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 8535d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit ExternalElementsAccessor(const char* name) 8545d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ElementsAccessorBase<ExternalElementsAccessorSubclass, 8555d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<Kind> >(name) {} 8565d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 85769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch protected: 8585d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 8595d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 86069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch friend class ElementsAccessorBase<ExternalElementsAccessorSubclass, 8615d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<Kind> >; 86269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 8635d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static MaybeObject* GetImpl(Object* receiver, 864592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch JSObject* obj, 8655d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t key, 8665d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch BackingStore* backing_store) { 867592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return 868592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) 869592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch ? backing_store->get(key) 870592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch : backing_store->GetHeap()->undefined_value(); 871592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 872592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 8735d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static MaybeObject* SetLengthImpl(JSObject* obj, 8745d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Object* length, 8755d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch BackingStore* backing_store) { 876592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // External arrays do not support changing their length. 877592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch UNREACHABLE(); 878592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return obj; 87969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 88069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 88169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual MaybeObject* Delete(JSObject* obj, 88269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key, 88369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) { 88469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // External arrays always ignore deletes. 88569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return obj->GetHeap()->true_value(); 88669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 8875d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 8885d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static bool HasElementImpl(Object* receiver, 8895d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch JSObject* holder, 8905d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t key, 8915d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch BackingStore* backing_store) { 8925d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t capacity = 8935d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store); 8945d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return key < capacity; 8955d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 89669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 89769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 89869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 89969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalByteElementsAccessor 90069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalByteElementsAccessor, 9015d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_BYTE_ELEMENTS> { 9025d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 9035d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit ExternalByteElementsAccessor(const char* name) 9045d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ExternalElementsAccessor<ExternalByteElementsAccessor, 9055d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_BYTE_ELEMENTS>(name) {} 90669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 90769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 90869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 90969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalUnsignedByteElementsAccessor 91069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalUnsignedByteElementsAccessor, 9115d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_UNSIGNED_BYTE_ELEMENTS> { 9125d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 9135d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit ExternalUnsignedByteElementsAccessor(const char* name) 9145d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ExternalElementsAccessor<ExternalUnsignedByteElementsAccessor, 9155d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_UNSIGNED_BYTE_ELEMENTS>(name) {} 91669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 91769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 91869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 91969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalShortElementsAccessor 92069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalShortElementsAccessor, 9215d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_SHORT_ELEMENTS> { 9225d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 9235d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit ExternalShortElementsAccessor(const char* name) 9245d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ExternalElementsAccessor<ExternalShortElementsAccessor, 9255d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_SHORT_ELEMENTS>(name) {} 92669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 92769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 92869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 92969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalUnsignedShortElementsAccessor 93069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalUnsignedShortElementsAccessor, 9315d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_UNSIGNED_SHORT_ELEMENTS> { 9325d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 9335d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit ExternalUnsignedShortElementsAccessor(const char* name) 9345d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ExternalElementsAccessor<ExternalUnsignedShortElementsAccessor, 9355d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_UNSIGNED_SHORT_ELEMENTS>(name) {} 93669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 93769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 93869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 93969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalIntElementsAccessor 94069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalIntElementsAccessor, 9415d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_INT_ELEMENTS> { 9425d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 9435d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit ExternalIntElementsAccessor(const char* name) 9445d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ExternalElementsAccessor<ExternalIntElementsAccessor, 9455d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_INT_ELEMENTS>(name) {} 94669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 94769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 94869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 94969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalUnsignedIntElementsAccessor 95069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalUnsignedIntElementsAccessor, 9515d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_UNSIGNED_INT_ELEMENTS> { 9525d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 9535d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit ExternalUnsignedIntElementsAccessor(const char* name) 9545d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ExternalElementsAccessor<ExternalUnsignedIntElementsAccessor, 9555d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_UNSIGNED_INT_ELEMENTS>(name) {} 95669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 95769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 95869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 95969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalFloatElementsAccessor 96069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalFloatElementsAccessor, 9615d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_FLOAT_ELEMENTS> { 9625d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 9635d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit ExternalFloatElementsAccessor(const char* name) 9645d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ExternalElementsAccessor<ExternalFloatElementsAccessor, 9655d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_FLOAT_ELEMENTS>(name) {} 96669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 96769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 96869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 96969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalDoubleElementsAccessor 97069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalDoubleElementsAccessor, 9715d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_DOUBLE_ELEMENTS> { 9725d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 9735d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit ExternalDoubleElementsAccessor(const char* name) 9745d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ExternalElementsAccessor<ExternalDoubleElementsAccessor, 9755d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_DOUBLE_ELEMENTS>(name) {} 97669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 97769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 97869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 97969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass PixelElementsAccessor 98069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<PixelElementsAccessor, 9815d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_PIXEL_ELEMENTS> { 9825d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 9835d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit PixelElementsAccessor(const char* name) 9845d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ExternalElementsAccessor<PixelElementsAccessor, 9855d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch EXTERNAL_PIXEL_ELEMENTS>(name) {} 98669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 98769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 98869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 98969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass DictionaryElementsAccessor 99069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ElementsAccessorBase<DictionaryElementsAccessor, 9915d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<DICTIONARY_ELEMENTS> > { 99269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch public: 9935d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit DictionaryElementsAccessor(const char* name) 9945d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ElementsAccessorBase<DictionaryElementsAccessor, 9955d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} 9965d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 997592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // Adjusts the length of the dictionary backing store and returns the new 998592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // length according to ES5 section 15.4.5.2 behavior. 999c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch static MaybeObject* SetLengthWithoutNormalize(SeededNumberDictionary* dict, 1000592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch JSArray* array, 1001592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch Object* length_object, 1002592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t length) { 1003592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (length == 0) { 1004592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // If the length of a slow array is reset to zero, we clear 1005592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // the array and flush backing storage. This has the added 1006592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // benefit that the array returns to fast mode. 1007592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch Object* obj; 1008592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch MaybeObject* maybe_obj = array->ResetElements(); 1009592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1010592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } else { 1011592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t new_length = length; 1012592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t old_length = static_cast<uint32_t>(array->length()->Number()); 1013592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (new_length < old_length) { 1014592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // Find last non-deletable element in range of elements to be 1015592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // deleted and adjust range accordingly. 1016592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch Heap* heap = array->GetHeap(); 1017592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch int capacity = dict->Capacity(); 1018592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch for (int i = 0; i < capacity; i++) { 1019592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch Object* key = dict->KeyAt(i); 1020592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (key->IsNumber()) { 1021592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t number = static_cast<uint32_t>(key->Number()); 1022592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (new_length <= number && number < old_length) { 1023592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch PropertyDetails details = dict->DetailsAt(i); 1024592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (details.IsDontDelete()) new_length = number + 1; 1025592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1026592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1027592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1028592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (new_length != length) { 1029592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch MaybeObject* maybe_object = heap->NumberFromUint32(new_length); 1030592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (!maybe_object->To(&length_object)) return maybe_object; 1031592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1032592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 1033592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // Remove elements that should be deleted. 1034592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch int removed_entries = 0; 1035592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch Object* the_hole_value = heap->the_hole_value(); 1036592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch for (int i = 0; i < capacity; i++) { 1037592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch Object* key = dict->KeyAt(i); 1038592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (key->IsNumber()) { 1039592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t number = static_cast<uint32_t>(key->Number()); 1040592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (new_length <= number && number < old_length) { 1041592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch dict->SetEntry(i, the_hole_value, the_hole_value); 1042592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch removed_entries++; 1043592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1044592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1045592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1046592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 1047592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // Update the number of elements. 1048592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch dict->ElementsRemoved(removed_entries); 1049592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1050592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1051592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return length_object; 1052592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1053592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 105469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static MaybeObject* DeleteCommon(JSObject* obj, 105569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key, 105669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) { 105769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Isolate* isolate = obj->GetIsolate(); 105869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Heap* heap = isolate->heap(); 105969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* backing_store = FixedArray::cast(obj->elements()); 106069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch bool is_arguments = 1061589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch (obj->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS); 106269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (is_arguments) { 106369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch backing_store = FixedArray::cast(backing_store->get(1)); 106469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1065c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary* dictionary = 1066c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::cast(backing_store); 106769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int entry = dictionary->FindEntry(key); 1068c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch if (entry != SeededNumberDictionary::kNotFound) { 106969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* result = dictionary->DeleteProperty(entry, mode); 107069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (result == heap->true_value()) { 107169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch MaybeObject* maybe_elements = dictionary->Shrink(key); 107269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* new_elements = NULL; 107369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!maybe_elements->To(&new_elements)) { 107469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return maybe_elements; 107569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 107669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (is_arguments) { 107769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray::cast(obj->elements())->set(1, new_elements); 107869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 107969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch obj->set_elements(new_elements); 108069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 108169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 108269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (mode == JSObject::STRICT_DELETION && 108369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch result == heap->false_value()) { 108469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // In strict mode, attempting to delete a non-configurable property 108569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // throws an exception. 108669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HandleScope scope(isolate); 108769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<Object> holder(obj); 108869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<Object> name = isolate->factory()->NewNumberFromUint(key); 108969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<Object> args[2] = { name, holder }; 109069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<Object> error = 109169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch isolate->factory()->NewTypeError("strict_delete_property", 109269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HandleVector(args, 2)); 109369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return isolate->Throw(*error); 109469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 109569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 109669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return heap->true_value(); 109769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 109869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 10995d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 11005d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t from_start, 11015d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArrayBase* to, 11025d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKind to_kind, 11035d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t to_start, 11045d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int copy_size) { 11055d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch switch (to_kind) { 11065d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch case FAST_SMI_ONLY_ELEMENTS: 11075d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch case FAST_ELEMENTS: 11085d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch CopyDictionaryToObjectElements( 11095d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch SeededNumberDictionary::cast(from), from_start, 11105d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray::cast(to), to_kind, to_start, copy_size); 11115d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return from; 11125d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch case FAST_DOUBLE_ELEMENTS: 11135d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch CopyDictionaryToDoubleElements( 11145d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch SeededNumberDictionary::cast(from), from_start, 11155d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedDoubleArray::cast(to), to_start, copy_size); 11165d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return from; 11175d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch default: 11185d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch UNREACHABLE(); 11195d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 11205d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return to->GetHeap()->undefined_value(); 11215d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 11225d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 11235d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 112469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch protected: 112569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch friend class ElementsAccessorBase<DictionaryElementsAccessor, 11265d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<DICTIONARY_ELEMENTS> >; 112769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 112869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual MaybeObject* Delete(JSObject* obj, 112969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key, 113069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) { 113169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return DeleteCommon(obj, key, mode); 113269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 113369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11345d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static MaybeObject* GetImpl(Object* receiver, 1135592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch JSObject* obj, 11365d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t key, 11375d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch SeededNumberDictionary* backing_store) { 113869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int entry = backing_store->FindEntry(key); 1139c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch if (entry != SeededNumberDictionary::kNotFound) { 114069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* element = backing_store->ValueAt(entry); 114169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch PropertyDetails details = backing_store->DetailsAt(entry); 114269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (details.type() == CALLBACKS) { 114369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return obj->GetElementWithCallback(receiver, 114469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch element, 114569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch key, 114669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch obj); 114769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 114869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return element; 114969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 115069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 115169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return obj->GetHeap()->the_hole_value(); 115269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 115369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11545d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static bool HasElementImpl(Object* receiver, 11555d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch JSObject* holder, 11565d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t key, 11575d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch SeededNumberDictionary* backing_store) { 11585d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return backing_store->FindEntry(key) != 11595d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch SeededNumberDictionary::kNotFound; 11605d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 11615d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 1162c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict, 1163592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t index) { 116469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* key = dict->KeyAt(index); 116569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return Smi::cast(key)->value(); 116669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 116769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 116869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 116969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11705d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdochclass NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< 11715d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch NonStrictArgumentsElementsAccessor, 11725d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> > { 11735d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 11745d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch explicit NonStrictArgumentsElementsAccessor(const char* name) 11755d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : ElementsAccessorBase< 11765d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch NonStrictArgumentsElementsAccessor, 11775d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >(name) {} 117869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch protected: 11795d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch friend class ElementsAccessorBase< 11805d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch NonStrictArgumentsElementsAccessor, 11815d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >; 118269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11835d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static MaybeObject* GetImpl(Object* receiver, 1184592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch JSObject* obj, 11855d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t key, 11865d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray* parameter_map) { 11875d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Object* probe = GetParameterMapArg(obj, parameter_map, key); 118869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!probe->IsTheHole()) { 118969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Context* context = Context::cast(parameter_map->get(0)); 119069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int context_index = Smi::cast(probe)->value(); 119169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(!context->get(context_index)->IsTheHole()); 119269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return context->get(context_index); 119369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 119469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Object is not mapped, defer to the arguments. 119569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 11965d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get( 11975d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch receiver, obj, key, arguments); 11985d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Object* result; 11995d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (!maybe_result->ToObject(&result)) return maybe_result; 12005d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // Elements of the arguments object in slow mode might be slow aliases. 12015d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (result->IsAliasedArgumentsEntry()) { 12025d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(result); 12035d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Context* context = Context::cast(parameter_map->get(0)); 12045d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int context_index = entry->aliased_context_slot(); 12055d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ASSERT(!context->get(context_index)->IsTheHole()); 12065d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return context->get(context_index); 12075d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } else { 12085d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return result; 12095d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 121069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 121169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 121269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 12135d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static MaybeObject* SetLengthImpl(JSObject* obj, 12145d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Object* length, 12155d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray* parameter_map) { 1216592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // TODO(mstarzinger): This was never implemented but will be used once we 1217592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // correctly implement [[DefineOwnProperty]] on arrays. 1218592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch UNIMPLEMENTED(); 1219592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return obj; 1220592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1221592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 122269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual MaybeObject* Delete(JSObject* obj, 1223592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t key, 122469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) { 122569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* parameter_map = FixedArray::cast(obj->elements()); 12265d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Object* probe = GetParameterMapArg(obj, parameter_map, key); 122769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!probe->IsTheHole()) { 122869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // TODO(kmillikin): We could check if this was the last aliased 122969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // parameter, and revert to normal elements in that case. That 123069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // would enable GC of the context. 123169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch parameter_map->set_the_hole(key + 2); 123269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 123369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 123469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (arguments->IsDictionary()) { 123569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); 123669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 1237592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return FastObjectElementsAccessor::DeleteCommon(obj, key); 123869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 123969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 124069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return obj->GetHeap()->true_value(); 124169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 124269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 12435d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 12445d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t from_start, 12455d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArrayBase* to, 12465d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKind to_kind, 12475d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t to_start, 12485d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch int copy_size) { 12495d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray* parameter_map = FixedArray::cast(from); 12505d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 12515d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); 12525d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return accessor->CopyElements(NULL, from_start, to, to_kind, 12535d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch to_start, copy_size, arguments); 12545d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 12555d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 1256592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch static uint32_t GetCapacityImpl(FixedArray* parameter_map) { 125769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 125869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return Max(static_cast<uint32_t>(parameter_map->length() - 2), 125969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ForArray(arguments)->GetCapacity(arguments)); 126069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 126169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1262592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch static uint32_t GetKeyForIndexImpl(FixedArray* dict, 1263592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t index) { 126469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return index; 126569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 126669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 12675d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static bool HasElementImpl(Object* receiver, 12685d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch JSObject* holder, 12695d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t key, 12705d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray* parameter_map) { 12715d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Object* probe = GetParameterMapArg(holder, parameter_map, key); 127269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!probe->IsTheHole()) { 127369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return true; 127469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 127569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 127669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); 12775d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); 127869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 127969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 128069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 128169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch private: 12825d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch static Object* GetParameterMapArg(JSObject* holder, 12835d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch FixedArray* parameter_map, 128469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key) { 12855d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t length = holder->IsJSArray() 12865d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ? Smi::cast(JSArray::cast(holder)->length())->value() 12875d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch : parameter_map->length(); 128869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return key < (length - 2 ) 128969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ? parameter_map->get(key + 2) 129069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : parameter_map->GetHeap()->the_hole_value(); 129169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 129269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 129369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 129469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 129569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { 129669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch switch (array->map()->instance_type()) { 129769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case FIXED_ARRAY_TYPE: 129869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (array->IsDictionary()) { 1299589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[DICTIONARY_ELEMENTS]; 130069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 1301589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[FAST_ELEMENTS]; 130269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 130369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_BYTE_ARRAY_TYPE: 1304589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_BYTE_ELEMENTS]; 130569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: 1306589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_UNSIGNED_BYTE_ELEMENTS]; 130769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_SHORT_ARRAY_TYPE: 1308589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_SHORT_ELEMENTS]; 130969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: 1310589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_UNSIGNED_SHORT_ELEMENTS]; 131169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_INT_ARRAY_TYPE: 1312589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_INT_ELEMENTS]; 131369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: 1314589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_UNSIGNED_INT_ELEMENTS]; 131569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_FLOAT_ARRAY_TYPE: 1316589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_FLOAT_ELEMENTS]; 131769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_DOUBLE_ARRAY_TYPE: 1318589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_DOUBLE_ELEMENTS]; 131969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_PIXEL_ARRAY_TYPE: 1320589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_PIXEL_ELEMENTS]; 132169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch default: 132269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch UNREACHABLE(); 132369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return NULL; 132469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 132569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 132669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 132769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 132869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid ElementsAccessor::InitializeOncePerProcess() { 132969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static struct ConcreteElementsAccessors { 13305d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#define ACCESSOR_STRUCT(Class, Kind, Store) Class* Kind##_handler; 1331592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch ELEMENTS_LIST(ACCESSOR_STRUCT) 1332592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch#undef ACCESSOR_STRUCT 1333592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } element_accessors = { 13345d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#define ACCESSOR_INIT(Class, Kind, Store) new Class(#Kind), 1335592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch ELEMENTS_LIST(ACCESSOR_INIT) 1336592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch#undef ACCESSOR_INIT 1337592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch }; 133869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 133969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static ElementsAccessor* accessor_array[] = { 13405d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch#define ACCESSOR_ARRAY(Class, Kind, Store) element_accessors.Kind##_handler, 1341592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch ELEMENTS_LIST(ACCESSOR_ARRAY) 1342592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch#undef ACCESSOR_ARRAY 134369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch }; 134469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1345592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) == 1346592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch kElementsKindCount); 1347592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 134869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch elements_accessors_ = accessor_array; 134969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 135069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 135169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 13525d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdochtemplate <typename ElementsAccessorSubclass, typename ElementsKindTraits> 13535d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen MurdochMaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, 13545d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch ElementsKindTraits>:: 13555d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch SetLengthImpl(JSObject* obj, 13565d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch Object* length, 13575d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch typename ElementsKindTraits::BackingStore* backing_store) { 1358592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch JSArray* array = JSArray::cast(obj); 1359592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 1360592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // Fast case: The new length fits into a Smi. 1361592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch MaybeObject* maybe_smi_length = length->ToSmi(); 1362592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch Object* smi_length = Smi::FromInt(0); 1363592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { 1364592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch const int value = Smi::cast(smi_length)->value(); 1365592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (value >= 0) { 1366592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch Object* new_length; 1367592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch MaybeObject* result = ElementsAccessorSubclass:: 1368592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch SetLengthWithoutNormalize(backing_store, array, smi_length, value); 1369592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (!result->ToObject(&new_length)) return result; 1370592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch ASSERT(new_length->IsSmi() || new_length->IsUndefined()); 1371592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (new_length->IsSmi()) { 1372592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch array->set_length(Smi::cast(new_length)); 1373592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return array; 1374592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1375592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } else { 1376592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return ThrowArrayLengthRangeError(array->GetHeap()); 1377592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1378592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1379592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 1380592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // Slow case: The new length does not fit into a Smi or conversion 1381592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // to slow elements is needed for other reasons. 1382592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (length->IsNumber()) { 1383592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch uint32_t value; 1384592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (length->ToArrayIndex(&value)) { 1385c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary* dictionary; 1386592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch MaybeObject* maybe_object = array->NormalizeElements(); 1387592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (!maybe_object->To(&dictionary)) return maybe_object; 1388592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch Object* new_length; 1389592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch MaybeObject* result = DictionaryElementsAccessor:: 1390592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch SetLengthWithoutNormalize(dictionary, array, length, value); 1391592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (!result->ToObject(&new_length)) return result; 1392592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch ASSERT(new_length->IsNumber()); 1393592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch array->set_length(new_length); 1394592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return array; 1395592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } else { 1396592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return ThrowArrayLengthRangeError(array->GetHeap()); 1397592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1398592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 1399592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 1400592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // Fall-back case: The new length is not a number so make the array 1401592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch // size one and set only element to length. 1402592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch FixedArray* new_backing_store; 1403592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch MaybeObject* maybe_obj = array->GetHeap()->AllocateFixedArray(1); 1404592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch if (!maybe_obj->To(&new_backing_store)) return maybe_obj; 1405592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch new_backing_store->set(0, length); 14065d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch { MaybeObject* result = array->SetContent(new_backing_store); 14075d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch if (result->IsFailure()) return result; 14085d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 1409592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch return array; 1410592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 1411592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 1412592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 141369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} } // namespace v8::internal 1414