Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(288)

Side by Side Diff: src/elements.cc

Issue 1193673002: Split setting array length from handling new Array(non-number) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Make GCC happy Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/conversions.h" 8 #include "src/conversions.h"
9 #include "src/elements.h" 9 #include "src/elements.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 1690 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 void ElementsAccessor::TearDown() { 1701 void ElementsAccessor::TearDown() {
1702 if (elements_accessors_ == NULL) return; 1702 if (elements_accessors_ == NULL) return;
1703 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; 1703 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind];
1704 ELEMENTS_LIST(ACCESSOR_DELETE) 1704 ELEMENTS_LIST(ACCESSOR_DELETE)
1705 #undef ACCESSOR_DELETE 1705 #undef ACCESSOR_DELETE
1706 elements_accessors_ = NULL; 1706 elements_accessors_ = NULL;
1707 } 1707 }
1708 1708
1709 1709
1710 template <typename ElementsAccessorSubclass, typename ElementsKindTraits> 1710 template <typename ElementsAccessorSubclass, typename ElementsKindTraits>
1711 MUST_USE_RESULT 1711 MUST_USE_RESULT MaybeHandle<Object> ElementsAccessorBase<
1712 MaybeHandle<Object> ElementsAccessorBase<ElementsAccessorSubclass, 1712 ElementsAccessorSubclass,
1713 ElementsKindTraits>:: 1713 ElementsKindTraits>::SetLengthImpl(Handle<JSObject> obj,
1714 SetLengthImpl(Handle<JSObject> obj, 1714 Handle<Object> length_obj,
1715 Handle<Object> length, 1715 Handle<FixedArrayBase> backing_store) {
1716 Handle<FixedArrayBase> backing_store) {
1717 Isolate* isolate = obj->GetIsolate();
1718 Handle<JSArray> array = Handle<JSArray>::cast(obj); 1716 Handle<JSArray> array = Handle<JSArray>::cast(obj);
1719 1717
1720 // Fast case: The new length fits into a Smi. 1718 uint32_t length = 0;
1721 Handle<Object> smi_length; 1719 CHECK(length_obj->ToArrayLength(&length));
1720 // Fast case: length fits in a smi.
1721 if (length <= Smi::kMaxValue) {
1722 Handle<Smi> smi(Smi::FromInt(length), obj->GetIsolate());
1723 Handle<Object> new_length =
1724 ElementsAccessorSubclass::SetLengthWithoutNormalize(backing_store,
1725 array, smi, length);
1726 DCHECK(!new_length.is_null());
1722 1727
1723 if (Object::ToSmi(isolate, length).ToHandle(&smi_length) && 1728 // Even though the proposed length was a smi, new_length could
1724 smi_length->IsSmi()) { 1729 // still be a heap number because SetLengthWithoutNormalize doesn't
1725 const int value = Handle<Smi>::cast(smi_length)->value(); 1730 // allow the array length property to drop below the index of
1726 if (value >= 0) { 1731 // non-deletable elements.
1727 Handle<Object> new_length = ElementsAccessorSubclass:: 1732 DCHECK(new_length->IsSmi() || new_length->IsHeapNumber() ||
1728 SetLengthWithoutNormalize(backing_store, array, smi_length, value); 1733 new_length->IsUndefined());
1729 DCHECK(!new_length.is_null()); 1734 if (new_length->IsSmi()) {
1730 1735 array->set_length(*Handle<Smi>::cast(new_length));
1731 // even though the proposed length was a smi, new_length could 1736 return array;
1732 // still be a heap number because SetLengthWithoutNormalize doesn't 1737 } else if (new_length->IsHeapNumber()) {
1733 // allow the array length property to drop below the index of 1738 array->set_length(*new_length);
1734 // non-deletable elements. 1739 return array;
1735 DCHECK(new_length->IsSmi() || new_length->IsHeapNumber() ||
1736 new_length->IsUndefined());
1737 if (new_length->IsSmi()) {
1738 array->set_length(*Handle<Smi>::cast(new_length));
1739 return array;
1740 } else if (new_length->IsHeapNumber()) {
1741 array->set_length(*new_length);
1742 return array;
1743 }
1744 } else {
1745 return ThrowArrayLengthRangeError(isolate);
1746 } 1740 }
1747 } 1741 }
1748 1742
1749 // Slow case: The new length does not fit into a Smi or conversion 1743 // Slow case: The new length does not fit into a Smi or conversion
1750 // to slow elements is needed for other reasons. 1744 // to slow elements is needed for other reasons.
1751 if (length->IsNumber()) { 1745 Handle<SeededNumberDictionary> dictionary =
1752 uint32_t value; 1746 JSObject::NormalizeElements(array);
1753 if (length->ToArrayLength(&value)) { 1747 DCHECK(!dictionary.is_null());
1754 Handle<SeededNumberDictionary> dictionary =
1755 JSObject::NormalizeElements(array);
1756 DCHECK(!dictionary.is_null());
1757 1748
1758 Handle<Object> new_length = DictionaryElementsAccessor:: 1749 Handle<Object> new_length =
1759 SetLengthWithoutNormalize(dictionary, array, length, value); 1750 DictionaryElementsAccessor::SetLengthWithoutNormalize(dictionary, array,
1760 DCHECK(!new_length.is_null()); 1751 length_obj, length);
1752 DCHECK(!new_length.is_null());
1761 1753
1762 DCHECK(new_length->IsNumber()); 1754 DCHECK(new_length->IsNumber());
1763 array->set_length(*new_length); 1755 array->set_length(*new_length);
1764 return array;
1765 } else {
1766 return ThrowArrayLengthRangeError(isolate);
1767 }
1768 }
1769
1770 // Fall-back case: The new length is not a number so make the array
1771 // size one and set only element to length.
1772 Handle<FixedArray> new_backing_store = isolate->factory()->NewFixedArray(1);
1773 new_backing_store->set(0, *length);
1774 JSArray::SetContent(array, new_backing_store);
1775 return array; 1756 return array;
1776 } 1757 }
1777 1758
1778 1759
1779 MaybeHandle<Object> ArrayConstructInitializeElements(Handle<JSArray> array, 1760 MaybeHandle<Object> ArrayConstructInitializeElements(Handle<JSArray> array,
1780 Arguments* args) { 1761 Arguments* args) {
1781 // Optimize the case where there is one argument and the argument is a 1762 if (args->length() == 0) {
1782 // small smi. 1763 // Optimize the case where there are no parameters passed.
1783 if (args->length() == 1) { 1764 JSArray::Initialize(array, JSArray::kPreallocatedArrayElements);
1784 Handle<Object> obj = args->at<Object>(0); 1765 return array;
1785 if (obj->IsSmi()) {
1786 int len = Handle<Smi>::cast(obj)->value();
1787 if (len > 0 && len < JSObject::kInitialMaxFastElementArray) {
1788 ElementsKind elements_kind = array->GetElementsKind();
1789 JSArray::Initialize(array, len, len);
1790 1766
1791 if (!IsFastHoleyElementsKind(elements_kind)) { 1767 } else if (args->length() == 1 && args->at<Object>(0)->IsNumber()) {
1792 elements_kind = GetHoleyElementsKind(elements_kind); 1768 uint32_t length;
1793 JSObject::TransitionElementsKind(array, elements_kind); 1769 if (!args->at<Object>(0)->ToArrayLength(&length)) {
1794 } 1770 return ThrowArrayLengthRangeError(array->GetIsolate());
1795 return array; 1771 }
1796 } else if (len == 0) { 1772
1797 JSArray::Initialize(array, JSArray::kPreallocatedArrayElements); 1773 // Optimize the case where there is one argument and the argument is a small
1798 return array; 1774 // smi.
1775 if (length > 0 && length < JSObject::kInitialMaxFastElementArray) {
1776 ElementsKind elements_kind = array->GetElementsKind();
1777 JSArray::Initialize(array, length, length);
1778
1779 if (!IsFastHoleyElementsKind(elements_kind)) {
1780 elements_kind = GetHoleyElementsKind(elements_kind);
1781 JSObject::TransitionElementsKind(array, elements_kind);
1799 } 1782 }
1783 return array;
1784 } else if (length == 0) {
1785 JSArray::Initialize(array, JSArray::kPreallocatedArrayElements);
1786 return array;
1800 } 1787 }
1801 1788
1802 // Take the argument as the length. 1789 // Take the argument as the length.
1803 JSArray::Initialize(array, 0); 1790 JSArray::Initialize(array, 0);
1804 1791 return JSArray::SetElementsLength(array, args->at<Object>(0));
1805 return JSArray::SetElementsLength(array, obj);
1806 }
1807
1808 // Optimize the case where there are no parameters passed.
1809 if (args->length() == 0) {
1810 JSArray::Initialize(array, JSArray::kPreallocatedArrayElements);
1811 return array;
1812 } 1792 }
1813 1793
1814 Factory* factory = array->GetIsolate()->factory(); 1794 Factory* factory = array->GetIsolate()->factory();
1815 1795
1816 // Set length and elements on the array. 1796 // Set length and elements on the array.
1817 int number_of_elements = args->length(); 1797 int number_of_elements = args->length();
1818 JSObject::EnsureCanContainElements( 1798 JSObject::EnsureCanContainElements(
1819 array, args, 0, number_of_elements, ALLOW_CONVERTED_DOUBLE_ELEMENTS); 1799 array, args, 0, number_of_elements, ALLOW_CONVERTED_DOUBLE_ELEMENTS);
1820 1800
1821 // Allocate an appropriately typed elements array. 1801 // Allocate an appropriately typed elements array.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1863 break; 1843 break;
1864 } 1844 }
1865 1845
1866 array->set_elements(*elms); 1846 array->set_elements(*elms);
1867 array->set_length(Smi::FromInt(number_of_elements)); 1847 array->set_length(Smi::FromInt(number_of_elements));
1868 return array; 1848 return array;
1869 } 1849 }
1870 1850
1871 } // namespace internal 1851 } // namespace internal
1872 } // namespace v8 1852 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698