13ef787dbeca8a5fb1086949cda830dccee07bfbdBen 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 343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Each concrete ElementsAccessor can handle exactly one ElementsKind, 363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// several abstract ElementsAccessor classes are used to allow sharing 373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// common code. 383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// 393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Inheritance hierarchy: 403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - ElementsAccessorBase (abstract) 413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - FastElementsAccessor (abstract) 423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - FastObjectElementsAccessor 433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - FastDoubleElementsAccessor 443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - ExternalElementsAccessor (abstract) 453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - ExternalByteElementsAccessor 463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - ExternalUnsignedByteElementsAccessor 473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - ExternalShortElementsAccessor 483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - ExternalUnsignedShortElementsAccessor 493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - ExternalIntElementsAccessor 503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - ExternalUnsignedIntElementsAccessor 513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - ExternalFloatElementsAccessor 523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - ExternalDoubleElementsAccessor 533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - PixelElementsAccessor 543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - DictionaryElementsAccessor 553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// - NonStrictArgumentsElementsAccessor 563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochnamespace v8 { 5969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochnamespace internal { 6069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 6169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// First argument in list is the accessor class, the second argument is the 633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// accessor ElementsKind, and the third is the backing store class. Use the 643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// fast element handler for smi-only arrays. The implementation is currently 653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// identical. Note that the order must match that of the ElementsKind enum for 663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// the |accessor_array[]| below to work. 673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define ELEMENTS_LIST(V) \ 683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(FastObjectElementsAccessor, FAST_SMI_ONLY_ELEMENTS, FixedArray) \ 693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(FastObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \ 703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(FastDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, FixedDoubleArray) \ 713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, \ 723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SeededNumberDictionary) \ 733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(NonStrictArgumentsElementsAccessor, NON_STRICT_ARGUMENTS_ELEMENTS, \ 743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray) \ 753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(ExternalByteElementsAccessor, EXTERNAL_BYTE_ELEMENTS, \ 763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalByteArray) \ 773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(ExternalUnsignedByteElementsAccessor, \ 783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_UNSIGNED_BYTE_ELEMENTS, ExternalUnsignedByteArray) \ 793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(ExternalShortElementsAccessor, EXTERNAL_SHORT_ELEMENTS, \ 803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalShortArray) \ 813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(ExternalUnsignedShortElementsAccessor, \ 823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_UNSIGNED_SHORT_ELEMENTS, ExternalUnsignedShortArray) \ 833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(ExternalIntElementsAccessor, EXTERNAL_INT_ELEMENTS, \ 843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalIntArray) \ 853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(ExternalUnsignedIntElementsAccessor, \ 863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_UNSIGNED_INT_ELEMENTS, ExternalUnsignedIntArray) \ 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(ExternalFloatElementsAccessor, \ 883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_FLOAT_ELEMENTS, ExternalFloatArray) \ 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(ExternalDoubleElementsAccessor, \ 903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_DOUBLE_ELEMENTS, ExternalDoubleArray) \ 913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch V(PixelElementsAccessor, EXTERNAL_PIXEL_ELEMENTS, ExternalPixelArray) 923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate<ElementsKind Kind> class ElementsKindTraits { 953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef FixedArrayBase BackingStore; 973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define ELEMENTS_TRAITS(Class, KindParam, Store) \ 1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate<> class ElementsKindTraits<KindParam> { \ 1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: \ 1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const ElementsKind Kind = KindParam; \ 1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef Store BackingStore; \ 1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochELEMENTS_LIST(ELEMENTS_TRAITS) 1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef ELEMENTS_TRAITS 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochElementsAccessor** ElementsAccessor::elements_accessors_; 11069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen 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 1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic Failure* ThrowArrayLengthRangeError(Heap* heap) { 1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HandleScope scope(heap->isolate()); 1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return heap->isolate()->Throw( 1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *heap->isolate()->factory()->NewRangeError("invalid_array_length", 1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HandleVector<Object>(NULL, 0))); 1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid CopyObjectToObjectElements(FixedArray* from, 1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind from_kind, 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* to, 1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind to_kind, 1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_start, 1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int raw_copy_size) { 1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(to->map() != HEAP->fixed_cow_array_map()); 1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS); 1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); 1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size = raw_copy_size; 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size < 0) { 1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size = Min(from->length() - from_start, 1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->length() - to_start); 1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already 1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // marked with the hole. 1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = to_start + copy_size; i < to->length(); ++i) { 1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(to->get(i)->IsTheHole()); 1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (copy_size + static_cast<int>(from_start)) <= from->length()); 1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (copy_size == 0) return; 1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address to_address = to->address() + FixedArray::kHeaderSize; 1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address from_address = from->address() + FixedArray::kHeaderSize; 1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CopyWords(reinterpret_cast<Object**>(to_address) + to_start, 1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Object**>(from_address) + from_start, 1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size); 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS) { 1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap* heap = from->GetHeap(); 1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!heap->InNewSpace(to)) { 1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->RecordWrites(to->address(), 1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->OffsetOfElementAt(to_start), 1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size); 1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->incremental_marking()->RecordWrites(to); 1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void CopyDictionaryToObjectElements(SeededNumberDictionary* from, 1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* to, 1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind to_kind, 1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_start, 1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int raw_copy_size) { 1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size = raw_copy_size; 1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap* heap = from->GetHeap(); 1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size < 0) { 1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size = from->max_number_key() + 1 - from_start; 1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already 1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // marked with the hole. 1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = to_start + copy_size; i < to->length(); ++i) { 1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(to->get(i)->IsTheHole()); 1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(to != from); 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (copy_size == 0) return; 2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_length = to->length(); 2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (to_start + copy_size > to_length) { 2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size = to_length - to_start; 2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < copy_size; i++) { 2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int entry = from->FindEntry(i + from_start); 2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry != SeededNumberDictionary::kNotFound) { 2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* value = from->ValueAt(entry); 2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!value->IsTheHole()); 2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->set(i + to_start, value, SKIP_WRITE_BARRIER); 2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->set_the_hole(i + to_start); 2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (to_kind == FAST_ELEMENTS) { 2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!heap->InNewSpace(to)) { 2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->RecordWrites(to->address(), 2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->OffsetOfElementAt(to_start), 2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size); 2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->incremental_marking()->RecordWrites(to); 2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( 2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedDoubleArray* from, 2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* to, 2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind to_kind, 2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_start, 2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int raw_copy_size) { 2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS); 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size = raw_copy_size; 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size < 0) { 2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size = Min(from->length() - from_start, 2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->length() - to_start); 2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already 2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // marked with the hole. 2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = to_start + copy_size; i < to->length(); ++i) { 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(to->get(i)->IsTheHole()); 2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (copy_size + static_cast<int>(from_start)) <= from->length()); 2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (copy_size == 0) return from; 2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < copy_size; ++i) { 2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (to_kind == FAST_SMI_ONLY_ELEMENTS) { 2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNIMPLEMENTED(); 2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Failure::Exception(); 2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* maybe_value = from->get(i + from_start); 2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* value; 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(to_kind == FAST_ELEMENTS); 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Because FAST_DOUBLE_ELEMENTS -> FAST_ELEMENT allocate HeapObjects 2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // iteratively, the allocate must succeed within a single GC cycle, 2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // otherwise the retry after the GC will also fail. In order to ensure 2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // that no GC is triggered, allocate HeapNumbers from old space if they 2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // can't be taken from new space. 2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!maybe_value->ToObject(&value)) { 2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory()); 2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap* heap = from->GetHeap(); 2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* maybe_value_object = 2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch heap->AllocateHeapNumber(from->get_scalar(i + from_start), 2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TENURED); 2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!maybe_value_object->ToObject(&value)) return maybe_value_object; 2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->set(i + to_start, value, UPDATE_WRITE_BARRIER); 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return to; 2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void CopyDoubleToDoubleElements(FixedDoubleArray* from, 2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedDoubleArray* to, 2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_start, 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int raw_copy_size) { 2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size = raw_copy_size; 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size < 0) { 2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size = Min(from->length() - from_start, 2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->length() - to_start); 2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = to_start + copy_size; i < to->length(); ++i) { 2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->set_the_hole(i); 2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (copy_size + static_cast<int>(from_start)) <= from->length()); 3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (copy_size == 0) return; 3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address to_address = to->address() + FixedDoubleArray::kHeaderSize; 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address from_address = from->address() + FixedDoubleArray::kHeaderSize; 3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to_address += kDoubleSize * to_start; 3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch from_address += kDoubleSize * from_start; 3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int words_per_double = (kDoubleSize / kPointerSize); 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CopyWords(reinterpret_cast<Object**>(to_address), 3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch reinterpret_cast<Object**>(from_address), 3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch words_per_double * copy_size); 3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void CopyObjectToDoubleElements(FixedArray* from, 3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedDoubleArray* to, 3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_start, 3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int raw_copy_size) { 3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size = raw_copy_size; 3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size < 0) { 3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || 3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size = from->length() - from_start; 3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = to_start + copy_size; i < to->length(); ++i) { 3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->set_the_hole(i); 3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && 3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (copy_size + static_cast<int>(from_start)) <= from->length()); 3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (copy_size == 0) return; 3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < copy_size; i++) { 3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* hole_or_object = from->get(i + from_start); 3373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (hole_or_object->IsTheHole()) { 3383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->set_the_hole(i + to_start); 3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 3403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->set(i + to_start, hole_or_object->Number()); 3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void CopyDictionaryToDoubleElements(SeededNumberDictionary* from, 3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedDoubleArray* to, 3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_start, 3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int raw_copy_size) { 3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size = raw_copy_size; 3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (copy_size < 0) { 3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(copy_size == ElementsAccessor::kCopyToEnd || 3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); 3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size = from->max_number_key() + 1 - from_start; 3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { 3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = to_start + copy_size; i < to->length(); ++i) { 3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->set_the_hole(i); 3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (copy_size == 0) return; 3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_length = to->length(); 3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (to_start + copy_size > to_length) { 3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch copy_size = to_length - to_start; 3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < copy_size; i++) { 3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int entry = from->FindEntry(i + from_start); 3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry != SeededNumberDictionary::kNotFound) { 3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->set(i + to_start, from->ValueAt(entry)->Number()); 3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to->set_the_hole(i + to_start); 3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Base class for element handler implementations. Contains the 37969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// the common logic for objects with different ElementsKinds. 38069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Subclasses must specialize method for which the element 38169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// implementation differs from the base class implementation. 38269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 38369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// This class is intended to be used in the following way: 38469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 38569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// class SomeElementsAccessor : 38669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// public ElementsAccessorBase<SomeElementsAccessor, 38769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// BackingStoreClass> { 38869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// ... 38969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// } 39069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 39169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// This is an example of the Curiously Recurring Template Pattern (see 39269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use 39369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// CRTP to guarantee aggressive compile time optimizations (i.e. inlining and 39469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// specialization of SomeElementsAccessor methods). 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename ElementsAccessorSubclass, 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename ElementsTraitsParam> 39769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ElementsAccessorBase : public ElementsAccessor { 39869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch protected: 3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit ElementsAccessorBase(const char* name) 4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ElementsAccessor(name) { } 4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef ElementsTraitsParam ElementsTraits; 4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef typename ElementsTraitsParam::BackingStore BackingStore; 4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual ElementsKind kind() const { return ElementsTraits::Kind; } 4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static bool HasElementImpl(Object* receiver, 4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject* holder, 4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t key, 4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BackingStore* backing_store) { 4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* element = 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsAccessorSubclass::GetImpl(receiver, holder, key, backing_store); 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return !element->IsTheHole(); 4145d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 4155d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool HasElement(Object* receiver, 4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject* holder, 4185d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch uint32_t key, 4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArrayBase* backing_store) { 4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (backing_store == NULL) { 4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch backing_store = holder->elements(); 4225d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ElementsAccessorSubclass::HasElementImpl( 4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch receiver, holder, key, BackingStore::cast(backing_store)); 4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual MaybeObject* Get(Object* receiver, 4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject* holder, 4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t key, 4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArrayBase* backing_store) { 4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (backing_store == NULL) { 4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch backing_store = holder->elements(); 4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ElementsAccessorSubclass::GetImpl( 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch receiver, holder, key, BackingStore::cast(backing_store)); 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* GetImpl(Object* receiver, 4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject* obj, 4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t key, 4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BackingStore* backing_store) { 4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) 4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? backing_store->get(key) 4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : backing_store->GetHeap()->the_hole_value(); 4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual MaybeObject* SetLength(JSArray* array, 4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* length) { 4493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ElementsAccessorSubclass::SetLengthImpl( 4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch array, length, BackingStore::cast(array->elements())); 4513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* SetLengthImpl(JSObject* obj, 4543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* length, 4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BackingStore* backing_store); 4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual MaybeObject* SetCapacityAndLength(JSArray* array, 4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int capacity, 4593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int length) { 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ElementsAccessorSubclass::SetFastElementsCapacityAndLength( 4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch array, 4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch capacity, 4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch length); 4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int capacity, 4683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int length) { 4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNIMPLEMENTED(); 4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return obj; 471c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch } 472c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 47369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual MaybeObject* Delete(JSObject* obj, 47469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key, 47569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) = 0; 47669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 4773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 4783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 4793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArrayBase* to, 4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind to_kind, 4813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_start, 4823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size) { 4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return NULL; 4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual MaybeObject* CopyElements(JSObject* from_holder, 4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArrayBase* to, 4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind to_kind, 4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_start, 4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size, 4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArrayBase* from) { 4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (from == NULL) { 4953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch from = from_holder->elements(); 4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (from->length() == 0) { 4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return from; 4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ElementsAccessorSubclass::CopyElementsImpl( 5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch from, from_start, to, to_kind, to_start, copy_size); 5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual MaybeObject* AddElementsToFixedArray(Object* receiver, 50585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch JSObject* holder, 5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* to, 5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArrayBase* from) { 50869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int len0 = to->length(); 50969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#ifdef DEBUG 51069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (FLAG_enable_slow_asserts) { 51169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (int i = 0; i < len0; i++) { 51269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(!to->get(i)->IsTheHole()); 51369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 51469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 51569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#endif 5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (from == NULL) { 5173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch from = holder->elements(); 5183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BackingStore* backing_store = BackingStore::cast(from); 5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store); 52169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 52269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Optimize if 'other' is empty. 52369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // We cannot optimize if 'this' is empty, as other may have holes. 52469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (len1 == 0) return to; 52569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 52669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Compute how many elements are not in other. 5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t extra = 0; 52869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (uint32_t y = 0; y < len1; y++) { 5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t key = 5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); 5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (ElementsAccessorSubclass::HasElementImpl( 5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch receiver, holder, key, backing_store)) { 53369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch MaybeObject* maybe_value = 5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsAccessorSubclass::GetImpl(receiver, holder, 5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key, backing_store); 53669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* value; 53769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!maybe_value->ToObject(&value)) return maybe_value; 53869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(!value->IsTheHole()); 53969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!HasKey(to, value)) { 54069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch extra++; 54169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 54269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 54369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 54469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 54569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (extra == 0) return to; 54669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 54769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Allocate the result 54869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* result; 54969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch MaybeObject* maybe_obj = 55069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch backing_store->GetHeap()->AllocateFixedArray(len0 + extra); 55169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!maybe_obj->To<FixedArray>(&result)) return maybe_obj; 55269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 55369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Fill in the content 55469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { 55569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch AssertNoAllocation no_gc; 55669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 55769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (int i = 0; i < len0; i++) { 55869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* e = to->get(i); 55969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(e->IsString() || e->IsNumber()); 56069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch result->set(i, e, mode); 56169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 56269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 56369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Fill in the extra values. 5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t index = 0; 56569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (uint32_t y = 0; y < len1; y++) { 5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t key = 5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); 5683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (ElementsAccessorSubclass::HasElementImpl( 5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch receiver, holder, key, backing_store)) { 57069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch MaybeObject* maybe_value = 5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsAccessorSubclass::GetImpl(receiver, holder, 5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key, backing_store); 57369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* value; 57469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!maybe_value->ToObject(&value)) return maybe_value; 57569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!value->IsTheHole() && !HasKey(to, value)) { 57669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch result->set(len0 + index, value); 57769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch index++; 57869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 57969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 58069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 58169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(extra == index); 58269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return result; 58369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 58469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 58569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch protected: 5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static uint32_t GetCapacityImpl(BackingStore* backing_store) { 58769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return backing_store->length(); 58869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 58969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 59069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { 5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ElementsAccessorSubclass::GetCapacityImpl( 5923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BackingStore::cast(backing_store)); 59369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 59469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static uint32_t GetKeyForIndexImpl(BackingStore* backing_store, 5963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t index) { 59769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return index; 59869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 59969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 60069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, 6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t index) { 6023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ElementsAccessorSubclass::GetKeyForIndexImpl( 6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BackingStore::cast(backing_store), index); 60469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 60569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 60669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch private: 60769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 60869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 60969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 61069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Super class for all fast element arrays. 6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate<typename FastElementsAccessorSubclass, 6133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename KindTraits, 6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int ElementSize> 61569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass FastElementsAccessor 6163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { 6175d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public: 6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit FastElementsAccessor(const char* name) 6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ElementsAccessorBase<FastElementsAccessorSubclass, 6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KindTraits>(name) {} 6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch protected: 6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>; 6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef typename KindTraits::BackingStore BackingStore; 6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Adjusts the length of the fast backing store or returns the new length or 6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // undefined in case conversion to a slow backing store should be performed. 6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* SetLengthWithoutNormalize(BackingStore* backing_store, 6293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSArray* array, 6303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* length_object, 6313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t length) { 6323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t old_capacity = backing_store->length(); 6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check whether the backing store should be shrunk. 6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (length <= old_capacity) { 6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (array->HasFastTypeElements()) { 6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* maybe_obj = array->EnsureWritableFastElements(); 6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!maybe_obj->To(&backing_store)) return maybe_obj; 6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (2 * length <= old_capacity) { 6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If more than half the elements won't be used, trim the array. 6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (length == 0) { 6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch array->initialize_elements(); 6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch backing_store->set_length(length); 6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address filler_start = backing_store->address() + 6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BackingStore::OffsetOfElementAt(length); 6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int filler_size = (old_capacity - length) * ElementSize; 6493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch array->GetHeap()->CreateFillerObjectAt(filler_start, filler_size); 6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 6523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Otherwise, fill the unused tail with holes. 6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int old_length = FastD2I(array->length()->Number()); 6543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = length; i < old_length; i++) { 6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch backing_store->set_the_hole(i); 6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return length_object; 6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check whether the backing store should be expanded. 6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t min = JSObject::NewElementsCapacity(old_capacity); 6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t new_capacity = length > min ? length : min; 6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!array->ShouldConvertToSlowElements(new_capacity)) { 6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* result = FastElementsAccessorSubclass:: 6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetFastElementsCapacityAndLength(array, new_capacity, length); 6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (result->IsFailure()) return result; 6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return length_object; 6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Request conversion to slow elements. 6723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return array->GetHeap()->undefined_value(); 6733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass FastObjectElementsAccessor 6783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : public FastElementsAccessor<FastObjectElementsAccessor, 6793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<FAST_ELEMENTS>, 6803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kPointerSize> { 6813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 6823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit FastObjectElementsAccessor(const char* name) 6833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : FastElementsAccessor<FastObjectElementsAccessor, 6843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<FAST_ELEMENTS>, 6853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kPointerSize>(name) {} 6863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 68769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static MaybeObject* DeleteCommon(JSObject* obj, 68869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key) { 6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(obj->HasFastElements() || 6903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch obj->HasFastSmiOnlyElements() || 6913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch obj->HasFastArgumentsElements()); 69269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Heap* heap = obj->GetHeap(); 69369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* backing_store = FixedArray::cast(obj->elements()); 69469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (backing_store->map() == heap->non_strict_arguments_elements_map()) { 69569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch backing_store = FixedArray::cast(backing_store->get(1)); 69669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 69769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* writable; 69869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch MaybeObject* maybe = obj->EnsureWritableFastElements(); 69969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!maybe->ToObject(&writable)) return maybe; 70069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch backing_store = FixedArray::cast(writable); 70169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 70269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t length = static_cast<uint32_t>( 70369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch obj->IsJSArray() 70469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ? Smi::cast(JSArray::cast(obj)->length())->value() 70569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : backing_store->length()); 70669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (key < length) { 70769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch backing_store->set_the_hole(key); 70869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // If an old space backing store is larger than a certain size and 70969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // has too few used values, normalize it. 71069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // To avoid doing the check on every delete we require at least 71169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // one adjacent hole to the value being deleted. 71269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* hole = heap->the_hole_value(); 71369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch const int kMinLengthForSparsenessCheck = 64; 71469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (backing_store->length() >= kMinLengthForSparsenessCheck && 71569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch !heap->InNewSpace(backing_store) && 71669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ((key > 0 && backing_store->get(key - 1) == hole) || 71769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch (key + 1 < length && backing_store->get(key + 1) == hole))) { 71869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int num_used = 0; 71969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (int i = 0; i < backing_store->length(); ++i) { 72069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (backing_store->get(i) != hole) ++num_used; 72169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Bail out early if more than 1/4 is used. 72269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (4 * num_used > backing_store->length()) break; 72369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 72469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (4 * num_used <= backing_store->length()) { 72569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch MaybeObject* result = obj->NormalizeElements(); 72669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (result->IsFailure()) return result; 72769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 72869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 72969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 73069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return heap->true_value(); 73169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 73269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 7333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 7343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 7353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArrayBase* to, 7363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind to_kind, 7373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_start, 7383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size) { 7393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (to_kind) { 7403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_SMI_ONLY_ELEMENTS: 7413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_ELEMENTS: { 7423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CopyObjectToObjectElements( 7433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray::cast(from), ElementsTraits::Kind, from_start, 7443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray::cast(to), to_kind, to_start, copy_size); 7453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return from; 7463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_DOUBLE_ELEMENTS: 7483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CopyObjectToDoubleElements( 7493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray::cast(from), from_start, 7503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedDoubleArray::cast(to), to_start, copy_size); 7513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return from; 7523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return to->GetHeap()->undefined_value(); 7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t capacity, 7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t length) { 7623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::SetFastElementsCapacityMode set_capacity_mode = 7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch obj->HasFastSmiOnlyElements() 7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? JSObject::kAllowSmiOnlyElements 7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : JSObject::kDontAllowSmiOnlyElements; 7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return obj->SetFastElementsCapacityAndLength(capacity, 7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch length, 7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch set_capacity_mode); 7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 771c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch protected: 7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch friend class FastElementsAccessor<FastObjectElementsAccessor, 7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<FAST_ELEMENTS>, 7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kPointerSize>; 7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 77669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual MaybeObject* Delete(JSObject* obj, 77769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key, 77869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) { 77969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return DeleteCommon(obj, key); 78069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 78169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 78269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 78369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 78469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass FastDoubleElementsAccessor 7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : public FastElementsAccessor<FastDoubleElementsAccessor, 7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<FAST_DOUBLE_ELEMENTS>, 7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kDoubleSize> { 7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit FastDoubleElementsAccessor(const char* name) 7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : FastElementsAccessor<FastDoubleElementsAccessor, 7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<FAST_DOUBLE_ELEMENTS>, 7923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kDoubleSize>(name) {} 7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, 7953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t capacity, 7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t length) { 7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return obj->SetFastDoubleElementsCapacityAndLength(capacity, length); 7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 80069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch protected: 80169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch friend class ElementsAccessorBase<FastDoubleElementsAccessor, 8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >; 8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch friend class FastElementsAccessor<FastDoubleElementsAccessor, 8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<FAST_DOUBLE_ELEMENTS>, 8053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kDoubleSize>; 8063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 8083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 8093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArrayBase* to, 8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind to_kind, 8113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_start, 8123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size) { 8133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (to_kind) { 8143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_SMI_ONLY_ELEMENTS: 8153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_ELEMENTS: 8163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return CopyDoubleToObjectElements( 8173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedDoubleArray::cast(from), from_start, FixedArray::cast(to), 8183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to_kind, to_start, copy_size); 8193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_DOUBLE_ELEMENTS: 8203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CopyDoubleToDoubleElements(FixedDoubleArray::cast(from), from_start, 8213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedDoubleArray::cast(to), 8223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to_start, copy_size); 8233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return from; 8243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 8253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 8263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return to->GetHeap()->undefined_value(); 8283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8295d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 83069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual MaybeObject* Delete(JSObject* obj, 83169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key, 83269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) { 83369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int length = obj->IsJSArray() 83469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ? Smi::cast(JSArray::cast(obj)->length())->value() 83569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : FixedDoubleArray::cast(obj->elements())->length(); 83669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (key < static_cast<uint32_t>(length)) { 83769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedDoubleArray::cast(obj->elements())->set_the_hole(key); 83869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 83969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return obj->GetHeap()->true_value(); 84069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 84169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 8423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static bool HasElementImpl(Object* receiver, 8433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject* holder, 8443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t key, 8453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedDoubleArray* backing_store) { 8463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return key < static_cast<uint32_t>(backing_store->length()) && 8473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !backing_store->is_the_hole(key); 84869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 84969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 85069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 85169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 85269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Super class for all external element arrays. 85369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochtemplate<typename ExternalElementsAccessorSubclass, 8543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind Kind> 85569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalElementsAccessor 85669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ElementsAccessorBase<ExternalElementsAccessorSubclass, 8573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<Kind> > { 8583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 8593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit ExternalElementsAccessor(const char* name) 8603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ElementsAccessorBase<ExternalElementsAccessorSubclass, 8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<Kind> >(name) {} 8623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 86369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch protected: 8643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 8653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 86669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch friend class ElementsAccessorBase<ExternalElementsAccessorSubclass, 8673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<Kind> >; 868592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 8693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* GetImpl(Object* receiver, 8703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject* obj, 8713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t key, 8723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BackingStore* backing_store) { 8733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return 8743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) 8753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? backing_store->get(key) 8763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : backing_store->GetHeap()->undefined_value(); 8773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 8783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* SetLengthImpl(JSObject* obj, 8803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* length, 8813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BackingStore* backing_store) { 8823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // External arrays do not support changing their length. 8833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 8843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return obj; 88569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 88669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 88769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual MaybeObject* Delete(JSObject* obj, 88869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key, 88969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) { 89069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // External arrays always ignore deletes. 89169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return obj->GetHeap()->true_value(); 89269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 8933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static bool HasElementImpl(Object* receiver, 8953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject* holder, 8963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t key, 8973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BackingStore* backing_store) { 8983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t capacity = 8993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store); 9003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return key < capacity; 9013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 90269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 90369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 90469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 90569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalByteElementsAccessor 90669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalByteElementsAccessor, 9073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_BYTE_ELEMENTS> { 9083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 9093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit ExternalByteElementsAccessor(const char* name) 9103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ExternalElementsAccessor<ExternalByteElementsAccessor, 9113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_BYTE_ELEMENTS>(name) {} 91269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 91369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 91469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 91569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalUnsignedByteElementsAccessor 91669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalUnsignedByteElementsAccessor, 9173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_UNSIGNED_BYTE_ELEMENTS> { 9183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 9193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit ExternalUnsignedByteElementsAccessor(const char* name) 9203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ExternalElementsAccessor<ExternalUnsignedByteElementsAccessor, 9213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_UNSIGNED_BYTE_ELEMENTS>(name) {} 92269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 92369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 92469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 92569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalShortElementsAccessor 92669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalShortElementsAccessor, 9273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_SHORT_ELEMENTS> { 9283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 9293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit ExternalShortElementsAccessor(const char* name) 9303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ExternalElementsAccessor<ExternalShortElementsAccessor, 9313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_SHORT_ELEMENTS>(name) {} 93269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 93369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 93469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 93569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalUnsignedShortElementsAccessor 93669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalUnsignedShortElementsAccessor, 9373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_UNSIGNED_SHORT_ELEMENTS> { 9383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 9393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit ExternalUnsignedShortElementsAccessor(const char* name) 9403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ExternalElementsAccessor<ExternalUnsignedShortElementsAccessor, 9413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_UNSIGNED_SHORT_ELEMENTS>(name) {} 94269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 94369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 94469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 94569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalIntElementsAccessor 94669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalIntElementsAccessor, 9473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_INT_ELEMENTS> { 9483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 9493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit ExternalIntElementsAccessor(const char* name) 9503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ExternalElementsAccessor<ExternalIntElementsAccessor, 9513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_INT_ELEMENTS>(name) {} 95269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 95369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 95469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 95569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalUnsignedIntElementsAccessor 95669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalUnsignedIntElementsAccessor, 9573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_UNSIGNED_INT_ELEMENTS> { 9583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 9593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit ExternalUnsignedIntElementsAccessor(const char* name) 9603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ExternalElementsAccessor<ExternalUnsignedIntElementsAccessor, 9613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_UNSIGNED_INT_ELEMENTS>(name) {} 96269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 96369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 96469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 96569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalFloatElementsAccessor 96669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalFloatElementsAccessor, 9673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_FLOAT_ELEMENTS> { 9683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 9693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit ExternalFloatElementsAccessor(const char* name) 9703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ExternalElementsAccessor<ExternalFloatElementsAccessor, 9713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_FLOAT_ELEMENTS>(name) {} 97269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 97369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 97469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 97569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ExternalDoubleElementsAccessor 97669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<ExternalDoubleElementsAccessor, 9773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_DOUBLE_ELEMENTS> { 9783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 9793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit ExternalDoubleElementsAccessor(const char* name) 9803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ExternalElementsAccessor<ExternalDoubleElementsAccessor, 9813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_DOUBLE_ELEMENTS>(name) {} 98269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 98369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 98469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 98569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass PixelElementsAccessor 98669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ExternalElementsAccessor<PixelElementsAccessor, 9873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_PIXEL_ELEMENTS> { 9883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 9893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit PixelElementsAccessor(const char* name) 9903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ExternalElementsAccessor<PixelElementsAccessor, 9913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EXTERNAL_PIXEL_ELEMENTS>(name) {} 99269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 99369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 99469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 99569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass DictionaryElementsAccessor 99669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : public ElementsAccessorBase<DictionaryElementsAccessor, 9973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<DICTIONARY_ELEMENTS> > { 99869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch public: 9993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit DictionaryElementsAccessor(const char* name) 10003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ElementsAccessorBase<DictionaryElementsAccessor, 10013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} 10023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Adjusts the length of the dictionary backing store and returns the new 10043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // length according to ES5 section 15.4.5.2 behavior. 10053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* SetLengthWithoutNormalize(SeededNumberDictionary* dict, 10063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSArray* array, 10073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* length_object, 10083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t length) { 10093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (length == 0) { 10103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the length of a slow array is reset to zero, we clear 10113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the array and flush backing storage. This has the added 10123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // benefit that the array returns to fast mode. 10133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* obj; 10143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* maybe_obj = array->ResetElements(); 10153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!maybe_obj->ToObject(&obj)) return maybe_obj; 10163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 10173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t new_length = length; 10183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t old_length = static_cast<uint32_t>(array->length()->Number()); 10193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (new_length < old_length) { 10203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Find last non-deletable element in range of elements to be 10213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // deleted and adjust range accordingly. 10223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Heap* heap = array->GetHeap(); 10233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int capacity = dict->Capacity(); 10243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < capacity; i++) { 10253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* key = dict->KeyAt(i); 10263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key->IsNumber()) { 10273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t number = static_cast<uint32_t>(key->Number()); 10283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (new_length <= number && number < old_length) { 10293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PropertyDetails details = dict->DetailsAt(i); 10303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (details.IsDontDelete()) new_length = number + 1; 10313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (new_length != length) { 10353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* maybe_object = heap->NumberFromUint32(new_length); 10363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!maybe_object->To(&length_object)) return maybe_object; 10373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Remove elements that should be deleted. 10403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int removed_entries = 0; 10413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* the_hole_value = heap->the_hole_value(); 10423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < capacity; i++) { 10433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* key = dict->KeyAt(i); 10443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key->IsNumber()) { 10453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t number = static_cast<uint32_t>(key->Number()); 10463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (new_length <= number && number < old_length) { 10473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch dict->SetEntry(i, the_hole_value, the_hole_value); 10483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch removed_entries++; 10493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Update the number of elements. 10543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch dict->ElementsRemoved(removed_entries); 10553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return length_object; 10583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 106069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static MaybeObject* DeleteCommon(JSObject* obj, 106169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key, 106269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) { 106369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Isolate* isolate = obj->GetIsolate(); 106469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Heap* heap = isolate->heap(); 106569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* backing_store = FixedArray::cast(obj->elements()); 106669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch bool is_arguments = 1067589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch (obj->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS); 106869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (is_arguments) { 106969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch backing_store = FixedArray::cast(backing_store->get(1)); 107069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1071c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary* dictionary = 1072c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::cast(backing_store); 107369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int entry = dictionary->FindEntry(key); 1074c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch if (entry != SeededNumberDictionary::kNotFound) { 107569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* result = dictionary->DeleteProperty(entry, mode); 107669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (result == heap->true_value()) { 107769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch MaybeObject* maybe_elements = dictionary->Shrink(key); 107869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* new_elements = NULL; 107969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!maybe_elements->To(&new_elements)) { 108069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return maybe_elements; 108169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 108269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (is_arguments) { 108369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray::cast(obj->elements())->set(1, new_elements); 108469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 108569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch obj->set_elements(new_elements); 108669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 108769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 108869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (mode == JSObject::STRICT_DELETION && 108969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch result == heap->false_value()) { 109069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // In strict mode, attempting to delete a non-configurable property 109169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // throws an exception. 109269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HandleScope scope(isolate); 109369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<Object> holder(obj); 109469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<Object> name = isolate->factory()->NewNumberFromUint(key); 109569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<Object> args[2] = { name, holder }; 109669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<Object> error = 109769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch isolate->factory()->NewTypeError("strict_delete_property", 109869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch HandleVector(args, 2)); 109969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return isolate->Throw(*error); 110069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 110169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 110269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return heap->true_value(); 110369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 110469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 11063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 11073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArrayBase* to, 11083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind to_kind, 11093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_start, 11103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size) { 11113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (to_kind) { 11123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_SMI_ONLY_ELEMENTS: 11133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_ELEMENTS: 11143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CopyDictionaryToObjectElements( 11153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SeededNumberDictionary::cast(from), from_start, 11163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray::cast(to), to_kind, to_start, copy_size); 11173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return from; 11183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case FAST_DOUBLE_ELEMENTS: 11193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CopyDictionaryToDoubleElements( 11203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SeededNumberDictionary::cast(from), from_start, 11213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedDoubleArray::cast(to), to_start, copy_size); 11223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return from; 11233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 11243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 11253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return to->GetHeap()->undefined_value(); 11273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 113069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch protected: 113169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch friend class ElementsAccessorBase<DictionaryElementsAccessor, 11323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<DICTIONARY_ELEMENTS> >; 113369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 113469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual MaybeObject* Delete(JSObject* obj, 113569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key, 113669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) { 113769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return DeleteCommon(obj, key, mode); 113869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 113969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* GetImpl(Object* receiver, 11413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject* obj, 11423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t key, 11433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SeededNumberDictionary* backing_store) { 114469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int entry = backing_store->FindEntry(key); 1145c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch if (entry != SeededNumberDictionary::kNotFound) { 114669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* element = backing_store->ValueAt(entry); 114769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch PropertyDetails details = backing_store->DetailsAt(entry); 114869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (details.type() == CALLBACKS) { 114969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return obj->GetElementWithCallback(receiver, 115069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch element, 115169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch key, 115269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch obj); 115369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 115469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return element; 115569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 115669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 115769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return obj->GetHeap()->the_hole_value(); 115869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 115969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static bool HasElementImpl(Object* receiver, 11613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject* holder, 11623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t key, 11633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SeededNumberDictionary* backing_store) { 11643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return backing_store->FindEntry(key) != 11653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SeededNumberDictionary::kNotFound; 11663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict, 11693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t index) { 117069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Object* key = dict->KeyAt(index); 117169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return Smi::cast(key)->value(); 117269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 117369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 117469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 117569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< 11773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonStrictArgumentsElementsAccessor, 11783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> > { 11793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 11803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch explicit NonStrictArgumentsElementsAccessor(const char* name) 11813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : ElementsAccessorBase< 11823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonStrictArgumentsElementsAccessor, 11833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >(name) {} 118469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch protected: 11853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch friend class ElementsAccessorBase< 11863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NonStrictArgumentsElementsAccessor, 11873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits<NON_STRICT_ARGUMENTS_ELEMENTS> >; 118869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* GetImpl(Object* receiver, 11903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject* obj, 11913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t key, 11923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* parameter_map) { 11933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* probe = GetParameterMapArg(obj, parameter_map, key); 119469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!probe->IsTheHole()) { 119569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Context* context = Context::cast(parameter_map->get(0)); 119669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch int context_index = Smi::cast(probe)->value(); 119769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ASSERT(!context->get(context_index)->IsTheHole()); 119869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return context->get(context_index); 119969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 120069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Object is not mapped, defer to the arguments. 120169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 12023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get( 12033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch receiver, obj, key, arguments); 12043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* result; 12053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!maybe_result->ToObject(&result)) return maybe_result; 12063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Elements of the arguments object in slow mode might be slow aliases. 12073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (result->IsAliasedArgumentsEntry()) { 12083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(result); 12093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Context* context = Context::cast(parameter_map->get(0)); 12103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int context_index = entry->aliased_context_slot(); 12113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!context->get(context_index)->IsTheHole()); 12123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return context->get(context_index); 12133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 12143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return result; 12153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 121669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 121769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 121869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 12193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* SetLengthImpl(JSObject* obj, 12203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* length, 12213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* parameter_map) { 12223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(mstarzinger): This was never implemented but will be used once we 12233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // correctly implement [[DefineOwnProperty]] on arrays. 12243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNIMPLEMENTED(); 12253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return obj; 12263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 122869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch virtual MaybeObject* Delete(JSObject* obj, 12293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t key, 123069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch JSReceiver::DeleteMode mode) { 123169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* parameter_map = FixedArray::cast(obj->elements()); 12323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* probe = GetParameterMapArg(obj, parameter_map, key); 123369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!probe->IsTheHole()) { 123469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // TODO(kmillikin): We could check if this was the last aliased 123569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // parameter, and revert to normal elements in that case. That 123669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // would enable GC of the context. 123769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch parameter_map->set_the_hole(key + 2); 123869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 123969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 124069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (arguments->IsDictionary()) { 124169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); 124269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 12433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return FastObjectElementsAccessor::DeleteCommon(obj, key); 124469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 124569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 124669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return obj->GetHeap()->true_value(); 124769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 124869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 12493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static MaybeObject* CopyElementsImpl(FixedArrayBase* from, 12503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t from_start, 12513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArrayBase* to, 12523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind to_kind, 12533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t to_start, 12543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int copy_size) { 12553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* parameter_map = FixedArray::cast(from); 12563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 12573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); 12583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return accessor->CopyElements(NULL, from_start, to, to_kind, 12593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch to_start, copy_size, arguments); 12603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 12613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 12623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static uint32_t GetCapacityImpl(FixedArray* parameter_map) { 126369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 126469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return Max(static_cast<uint32_t>(parameter_map->length() - 2), 126569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ForArray(arguments)->GetCapacity(arguments)); 126669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 126769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 12683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static uint32_t GetKeyForIndexImpl(FixedArray* dict, 12693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t index) { 127069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return index; 127169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 127269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 12733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static bool HasElementImpl(Object* receiver, 12743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject* holder, 12753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t key, 12763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* parameter_map) { 12773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* probe = GetParameterMapArg(holder, parameter_map, key); 127869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (!probe->IsTheHole()) { 127969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return true; 128069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 128169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 128269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); 12833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); 128469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 128569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 128669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 128769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch private: 12883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static Object* GetParameterMapArg(JSObject* holder, 12893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* parameter_map, 129069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch uint32_t key) { 12913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t length = holder->IsJSArray() 12923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? Smi::cast(JSArray::cast(holder)->length())->value() 12933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : parameter_map->length(); 129469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return key < (length - 2 ) 129569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ? parameter_map->get(key + 2) 129669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch : parameter_map->GetHeap()->the_hole_value(); 129769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 129869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 129969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 130069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 130169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { 130269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch switch (array->map()->instance_type()) { 130369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case FIXED_ARRAY_TYPE: 130469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (array->IsDictionary()) { 1305589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[DICTIONARY_ELEMENTS]; 130669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } else { 1307589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[FAST_ELEMENTS]; 130869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 130969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_BYTE_ARRAY_TYPE: 1310589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_BYTE_ELEMENTS]; 131169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: 1312589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_UNSIGNED_BYTE_ELEMENTS]; 131369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_SHORT_ARRAY_TYPE: 1314589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_SHORT_ELEMENTS]; 131569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: 1316589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_UNSIGNED_SHORT_ELEMENTS]; 131769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_INT_ARRAY_TYPE: 1318589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_INT_ELEMENTS]; 131969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: 1320589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_UNSIGNED_INT_ELEMENTS]; 132169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_FLOAT_ARRAY_TYPE: 1322589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_FLOAT_ELEMENTS]; 132369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_DOUBLE_ARRAY_TYPE: 1324589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_DOUBLE_ELEMENTS]; 132569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch case EXTERNAL_PIXEL_ARRAY_TYPE: 1326589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return elements_accessors_[EXTERNAL_PIXEL_ELEMENTS]; 132769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch default: 132869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch UNREACHABLE(); 132969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return NULL; 133069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 133169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 133269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 133369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 133469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid ElementsAccessor::InitializeOncePerProcess() { 133569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static struct ConcreteElementsAccessors { 13363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define ACCESSOR_STRUCT(Class, Kind, Store) Class* Kind##_handler; 13373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ELEMENTS_LIST(ACCESSOR_STRUCT) 13383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef ACCESSOR_STRUCT 13393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } element_accessors = { 13403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define ACCESSOR_INIT(Class, Kind, Store) new Class(#Kind), 13413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ELEMENTS_LIST(ACCESSOR_INIT) 13423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef ACCESSOR_INIT 13433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 134469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 134569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch static ElementsAccessor* accessor_array[] = { 13463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define ACCESSOR_ARRAY(Class, Kind, Store) element_accessors.Kind##_handler, 13473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ELEMENTS_LIST(ACCESSOR_ARRAY) 13483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef ACCESSOR_ARRAY 134969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch }; 135069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 13513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) == 13523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kElementsKindCount); 13533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 135469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch elements_accessors_ = accessor_array; 135569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 135669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 135769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 13583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochtemplate <typename ElementsAccessorSubclass, typename ElementsKindTraits> 13593ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, 13603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKindTraits>:: 13613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetLengthImpl(JSObject* obj, 13623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* length, 13633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch typename ElementsKindTraits::BackingStore* backing_store) { 13643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSArray* array = JSArray::cast(obj); 13653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Fast case: The new length fits into a Smi. 13673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* maybe_smi_length = length->ToSmi(); 13683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* smi_length = Smi::FromInt(0); 13693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { 13703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const int value = Smi::cast(smi_length)->value(); 13713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (value >= 0) { 13723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* new_length; 13733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* result = ElementsAccessorSubclass:: 13743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetLengthWithoutNormalize(backing_store, array, smi_length, value); 13753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!result->ToObject(&new_length)) return result; 13763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(new_length->IsSmi() || new_length->IsUndefined()); 13773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (new_length->IsSmi()) { 13783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch array->set_length(Smi::cast(new_length)); 13793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return array; 13803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 13823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ThrowArrayLengthRangeError(array->GetHeap()); 13833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 13853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Slow case: The new length does not fit into a Smi or conversion 13873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // to slow elements is needed for other reasons. 13883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (length->IsNumber()) { 13893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t value; 13903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (length->ToArrayIndex(&value)) { 13913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SeededNumberDictionary* dictionary; 13923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* maybe_object = array->NormalizeElements(); 13933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!maybe_object->To(&dictionary)) return maybe_object; 13943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* new_length; 13953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* result = DictionaryElementsAccessor:: 13963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetLengthWithoutNormalize(dictionary, array, length, value); 13973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!result->ToObject(&new_length)) return result; 13983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(new_length->IsNumber()); 13993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch array->set_length(new_length); 14003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return array; 14013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 14023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ThrowArrayLengthRangeError(array->GetHeap()); 14033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Fall-back case: The new length is not a number so make the array 14073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // size one and set only element to length. 14083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray* new_backing_store; 14093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MaybeObject* maybe_obj = array->GetHeap()->AllocateFixedArray(1); 14103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!maybe_obj->To(&new_backing_store)) return maybe_obj; 14113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch new_backing_store->set(0, length); 14123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { MaybeObject* result = array->SetContent(new_backing_store); 14133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (result->IsFailure()) return result; 14143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return array; 14163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 14173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 14183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 141969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} } // namespace v8::internal 1420