OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 750 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 } | 761 } |
762 | 762 |
763 MUST_USE_RESULT static MaybeObject* SetFastElementsCapacityAndLength( | 763 MUST_USE_RESULT static MaybeObject* SetFastElementsCapacityAndLength( |
764 JSObject* obj, | 764 JSObject* obj, |
765 int capacity, | 765 int capacity, |
766 int length) { | 766 int length) { |
767 UNIMPLEMENTED(); | 767 UNIMPLEMENTED(); |
768 return obj; | 768 return obj; |
769 } | 769 } |
770 | 770 |
771 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj, | 771 MUST_USE_RESULT virtual Handle<Object> Delete( |
772 uint32_t key, | 772 Handle<JSObject> obj, |
773 JSReceiver::DeleteMode mode) = 0; | 773 uint32_t key, |
| 774 JSReceiver::DeleteMode mode) = 0; |
774 | 775 |
775 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 776 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
776 uint32_t from_start, | 777 uint32_t from_start, |
777 FixedArrayBase* to, | 778 FixedArrayBase* to, |
778 ElementsKind from_kind, | 779 ElementsKind from_kind, |
779 uint32_t to_start, | 780 uint32_t to_start, |
780 int packed_size, | 781 int packed_size, |
781 int copy_size) { | 782 int copy_size) { |
782 UNREACHABLE(); | 783 UNREACHABLE(); |
783 return NULL; | 784 return NULL; |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 Handle<FixedArrayBase> backing_store, | 993 Handle<FixedArrayBase> backing_store, |
993 Handle<JSArray> array, | 994 Handle<JSArray> array, |
994 Handle<Object> length_object, | 995 Handle<Object> length_object, |
995 uint32_t length) { | 996 uint32_t length) { |
996 CALL_HEAP_FUNCTION(array->GetIsolate(), | 997 CALL_HEAP_FUNCTION(array->GetIsolate(), |
997 SetLengthWithoutNormalize( | 998 SetLengthWithoutNormalize( |
998 *backing_store, *array, *length_object, length), | 999 *backing_store, *array, *length_object, length), |
999 Object); | 1000 Object); |
1000 } | 1001 } |
1001 | 1002 |
1002 static MaybeObject* DeleteCommon(JSObject* obj, | 1003 static Handle<Object> DeleteCommon(Handle<JSObject> obj, |
1003 uint32_t key, | 1004 uint32_t key, |
1004 JSReceiver::DeleteMode mode) { | 1005 JSReceiver::DeleteMode mode) { |
1005 ASSERT(obj->HasFastSmiOrObjectElements() || | 1006 ASSERT(obj->HasFastSmiOrObjectElements() || |
1006 obj->HasFastDoubleElements() || | 1007 obj->HasFastDoubleElements() || |
1007 obj->HasFastArgumentsElements()); | 1008 obj->HasFastArgumentsElements()); |
| 1009 Isolate* isolate = obj->GetIsolate(); |
1008 Heap* heap = obj->GetHeap(); | 1010 Heap* heap = obj->GetHeap(); |
1009 Object* elements = obj->elements(); | 1011 Handle<Object> elements = handle(obj->elements(), isolate); |
1010 if (elements == heap->empty_fixed_array()) { | 1012 if (*elements == heap->empty_fixed_array()) { |
1011 return heap->true_value(); | 1013 return isolate->factory()->true_value(); |
1012 } | 1014 } |
1013 typename KindTraits::BackingStore* backing_store = | 1015 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); |
1014 KindTraits::BackingStore::cast(elements); | |
1015 bool is_sloppy_arguments_elements_map = | 1016 bool is_sloppy_arguments_elements_map = |
1016 backing_store->map() == heap->sloppy_arguments_elements_map(); | 1017 backing_store->map() == heap->sloppy_arguments_elements_map(); |
1017 if (is_sloppy_arguments_elements_map) { | 1018 if (is_sloppy_arguments_elements_map) { |
1018 backing_store = KindTraits::BackingStore::cast( | 1019 backing_store = Handle<BackingStore>::cast( |
1019 FixedArray::cast(backing_store)->get(1)); | 1020 handle(Handle<FixedArray>::cast(backing_store)->get(1), isolate)); |
1020 } | 1021 } |
1021 uint32_t length = static_cast<uint32_t>( | 1022 uint32_t length = static_cast<uint32_t>( |
1022 obj->IsJSArray() | 1023 obj->IsJSArray() |
1023 ? Smi::cast(JSArray::cast(obj)->length())->value() | 1024 ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value() |
1024 : backing_store->length()); | 1025 : backing_store->length()); |
1025 if (key < length) { | 1026 if (key < length) { |
1026 if (!is_sloppy_arguments_elements_map) { | 1027 if (!is_sloppy_arguments_elements_map) { |
1027 ElementsKind kind = KindTraits::Kind; | 1028 ElementsKind kind = KindTraits::Kind; |
1028 if (IsFastPackedElementsKind(kind)) { | 1029 if (IsFastPackedElementsKind(kind)) { |
1029 MaybeObject* transitioned = | 1030 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); |
1030 obj->TransitionElementsKind(GetHoleyElementsKind(kind)); | |
1031 if (transitioned->IsFailure()) return transitioned; | |
1032 } | 1031 } |
1033 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { | 1032 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { |
1034 Object* writable; | 1033 Handle<Object> writable = JSObject::EnsureWritableFastElements(obj); |
1035 MaybeObject* maybe = obj->EnsureWritableFastElements(); | 1034 backing_store = Handle<BackingStore>::cast(writable); |
1036 if (!maybe->ToObject(&writable)) return maybe; | |
1037 backing_store = KindTraits::BackingStore::cast(writable); | |
1038 } | 1035 } |
1039 } | 1036 } |
1040 backing_store->set_the_hole(key); | 1037 backing_store->set_the_hole(key); |
1041 // If an old space backing store is larger than a certain size and | 1038 // If an old space backing store is larger than a certain size and |
1042 // has too few used values, normalize it. | 1039 // has too few used values, normalize it. |
1043 // To avoid doing the check on every delete we require at least | 1040 // To avoid doing the check on every delete we require at least |
1044 // one adjacent hole to the value being deleted. | 1041 // one adjacent hole to the value being deleted. |
1045 const int kMinLengthForSparsenessCheck = 64; | 1042 const int kMinLengthForSparsenessCheck = 64; |
1046 if (backing_store->length() >= kMinLengthForSparsenessCheck && | 1043 if (backing_store->length() >= kMinLengthForSparsenessCheck && |
1047 !heap->InNewSpace(backing_store) && | 1044 !heap->InNewSpace(*backing_store) && |
1048 ((key > 0 && backing_store->is_the_hole(key - 1)) || | 1045 ((key > 0 && backing_store->is_the_hole(key - 1)) || |
1049 (key + 1 < length && backing_store->is_the_hole(key + 1)))) { | 1046 (key + 1 < length && backing_store->is_the_hole(key + 1)))) { |
1050 int num_used = 0; | 1047 int num_used = 0; |
1051 for (int i = 0; i < backing_store->length(); ++i) { | 1048 for (int i = 0; i < backing_store->length(); ++i) { |
1052 if (!backing_store->is_the_hole(i)) ++num_used; | 1049 if (!backing_store->is_the_hole(i)) ++num_used; |
1053 // Bail out early if more than 1/4 is used. | 1050 // Bail out early if more than 1/4 is used. |
1054 if (4 * num_used > backing_store->length()) break; | 1051 if (4 * num_used > backing_store->length()) break; |
1055 } | 1052 } |
1056 if (4 * num_used <= backing_store->length()) { | 1053 if (4 * num_used <= backing_store->length()) { |
1057 MaybeObject* result = obj->NormalizeElements(); | 1054 JSObject::NormalizeElements(obj); |
1058 if (result->IsFailure()) return result; | |
1059 } | 1055 } |
1060 } | 1056 } |
1061 } | 1057 } |
1062 return heap->true_value(); | 1058 return isolate->factory()->true_value(); |
1063 } | 1059 } |
1064 | 1060 |
1065 virtual MaybeObject* Delete(JSObject* obj, | 1061 virtual Handle<Object> Delete(Handle<JSObject> obj, |
1066 uint32_t key, | 1062 uint32_t key, |
1067 JSReceiver::DeleteMode mode) { | 1063 JSReceiver::DeleteMode mode) { |
1068 return DeleteCommon(obj, key, mode); | 1064 return DeleteCommon(obj, key, mode); |
1069 } | 1065 } |
1070 | 1066 |
1071 static bool HasElementImpl( | 1067 static bool HasElementImpl( |
1072 Object* receiver, | 1068 Object* receiver, |
1073 JSObject* holder, | 1069 JSObject* holder, |
1074 uint32_t key, | 1070 uint32_t key, |
1075 FixedArrayBase* backing_store) { | 1071 FixedArrayBase* backing_store) { |
1076 if (key >= static_cast<uint32_t>(backing_store->length())) { | 1072 if (key >= static_cast<uint32_t>(backing_store->length())) { |
1077 return false; | 1073 return false; |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1389 | 1385 |
1390 MUST_USE_RESULT static Handle<Object> SetLengthImpl( | 1386 MUST_USE_RESULT static Handle<Object> SetLengthImpl( |
1391 Handle<JSObject> obj, | 1387 Handle<JSObject> obj, |
1392 Handle<Object> length, | 1388 Handle<Object> length, |
1393 Handle<FixedArrayBase> backing_store) { | 1389 Handle<FixedArrayBase> backing_store) { |
1394 // External arrays do not support changing their length. | 1390 // External arrays do not support changing their length. |
1395 UNREACHABLE(); | 1391 UNREACHABLE(); |
1396 return obj; | 1392 return obj; |
1397 } | 1393 } |
1398 | 1394 |
1399 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj, | 1395 MUST_USE_RESULT virtual Handle<Object> Delete(Handle<JSObject> obj, |
1400 uint32_t key, | 1396 uint32_t key, |
1401 JSReceiver::DeleteMode mode) { | 1397 JSReceiver::DeleteMode mode) { |
1402 // External arrays always ignore deletes. | 1398 // External arrays always ignore deletes. |
1403 return obj->GetHeap()->true_value(); | 1399 return obj->GetIsolate()->factory()->true_value(); |
1404 } | 1400 } |
1405 | 1401 |
1406 static bool HasElementImpl(Object* receiver, | 1402 static bool HasElementImpl(Object* receiver, |
1407 JSObject* holder, | 1403 JSObject* holder, |
1408 uint32_t key, | 1404 uint32_t key, |
1409 FixedArrayBase* backing_store) { | 1405 FixedArrayBase* backing_store) { |
1410 uint32_t capacity = | 1406 uint32_t capacity = |
1411 AccessorClass::GetCapacityImpl(backing_store); | 1407 AccessorClass::GetCapacityImpl(backing_store); |
1412 return key < capacity; | 1408 return key < capacity; |
1413 } | 1409 } |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 } | 1544 } |
1549 if (is_arguments) { | 1545 if (is_arguments) { |
1550 FixedArray::cast(obj->elements())->set(1, new_elements); | 1546 FixedArray::cast(obj->elements())->set(1, new_elements); |
1551 } else { | 1547 } else { |
1552 obj->set_elements(new_elements); | 1548 obj->set_elements(new_elements); |
1553 } | 1549 } |
1554 } | 1550 } |
1555 return heap->true_value(); | 1551 return heap->true_value(); |
1556 } | 1552 } |
1557 | 1553 |
| 1554 // TODO(ishell): Temporary wrapper until handlified. |
| 1555 MUST_USE_RESULT static Handle<Object> DeleteCommon( |
| 1556 Handle<JSObject> obj, |
| 1557 uint32_t key, |
| 1558 JSReceiver::DeleteMode mode) { |
| 1559 CALL_HEAP_FUNCTION(obj->GetIsolate(), |
| 1560 DeleteCommon(*obj, key, mode), |
| 1561 Object); |
| 1562 } |
| 1563 |
1558 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1564 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
1559 uint32_t from_start, | 1565 uint32_t from_start, |
1560 FixedArrayBase* to, | 1566 FixedArrayBase* to, |
1561 ElementsKind from_kind, | 1567 ElementsKind from_kind, |
1562 uint32_t to_start, | 1568 uint32_t to_start, |
1563 int packed_size, | 1569 int packed_size, |
1564 int copy_size) { | 1570 int copy_size) { |
1565 UNREACHABLE(); | 1571 UNREACHABLE(); |
1566 return NULL; | 1572 return NULL; |
1567 } | 1573 } |
1568 | 1574 |
1569 | 1575 |
1570 protected: | 1576 protected: |
1571 friend class ElementsAccessorBase<DictionaryElementsAccessor, | 1577 friend class ElementsAccessorBase<DictionaryElementsAccessor, |
1572 ElementsKindTraits<DICTIONARY_ELEMENTS> >; | 1578 ElementsKindTraits<DICTIONARY_ELEMENTS> >; |
1573 | 1579 |
1574 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj, | 1580 MUST_USE_RESULT virtual Handle<Object> Delete(Handle<JSObject> obj, |
1575 uint32_t key, | 1581 uint32_t key, |
1576 JSReceiver::DeleteMode mode) { | 1582 JSReceiver::DeleteMode mode) { |
1577 return DeleteCommon(obj, key, mode); | 1583 return DeleteCommon(obj, key, mode); |
1578 } | 1584 } |
1579 | 1585 |
1580 MUST_USE_RESULT static MaybeObject* GetImpl( | 1586 MUST_USE_RESULT static MaybeObject* GetImpl( |
1581 Object* receiver, | 1587 Object* receiver, |
1582 JSObject* obj, | 1588 JSObject* obj, |
1583 uint32_t key, | 1589 uint32_t key, |
1584 FixedArrayBase* store) { | 1590 FixedArrayBase* store) { |
1585 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); | 1591 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); |
1586 int entry = backing_store->FindEntry(key); | 1592 int entry = backing_store->FindEntry(key); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1756 MUST_USE_RESULT static Handle<Object> SetLengthImpl( | 1762 MUST_USE_RESULT static Handle<Object> SetLengthImpl( |
1757 Handle<JSObject> obj, | 1763 Handle<JSObject> obj, |
1758 Handle<Object> length, | 1764 Handle<Object> length, |
1759 Handle<FixedArrayBase> parameter_map) { | 1765 Handle<FixedArrayBase> parameter_map) { |
1760 // TODO(mstarzinger): This was never implemented but will be used once we | 1766 // TODO(mstarzinger): This was never implemented but will be used once we |
1761 // correctly implement [[DefineOwnProperty]] on arrays. | 1767 // correctly implement [[DefineOwnProperty]] on arrays. |
1762 UNIMPLEMENTED(); | 1768 UNIMPLEMENTED(); |
1763 return obj; | 1769 return obj; |
1764 } | 1770 } |
1765 | 1771 |
1766 MUST_USE_RESULT virtual MaybeObject* Delete(JSObject* obj, | 1772 MUST_USE_RESULT virtual Handle<Object> Delete(Handle<JSObject> obj, |
1767 uint32_t key, | 1773 uint32_t key, |
1768 JSReceiver::DeleteMode mode) { | 1774 JSReceiver::DeleteMode mode) { |
1769 FixedArray* parameter_map = FixedArray::cast(obj->elements()); | 1775 Isolate* isolate = obj->GetIsolate(); |
1770 Object* probe = GetParameterMapArg(obj, parameter_map, key); | 1776 Handle<FixedArray> parameter_map = |
| 1777 handle(FixedArray::cast(obj->elements()), isolate); |
| 1778 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); |
1771 if (!probe->IsTheHole()) { | 1779 if (!probe->IsTheHole()) { |
1772 // TODO(kmillikin): We could check if this was the last aliased | 1780 // TODO(kmillikin): We could check if this was the last aliased |
1773 // parameter, and revert to normal elements in that case. That | 1781 // parameter, and revert to normal elements in that case. That |
1774 // would enable GC of the context. | 1782 // would enable GC of the context. |
1775 parameter_map->set_the_hole(key + 2); | 1783 parameter_map->set_the_hole(key + 2); |
1776 } else { | 1784 } else { |
1777 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 1785 Handle<FixedArray> arguments = |
| 1786 handle(FixedArray::cast(parameter_map->get(1)), isolate); |
1778 if (arguments->IsDictionary()) { | 1787 if (arguments->IsDictionary()) { |
1779 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); | 1788 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); |
1780 } else { | 1789 } else { |
1781 // It's difficult to access the version of DeleteCommon that is declared | 1790 // It's difficult to access the version of DeleteCommon that is declared |
1782 // in the templatized super class, call the concrete implementation in | 1791 // in the templatized super class, call the concrete implementation in |
1783 // the class for the most generalized ElementsKind subclass. | 1792 // the class for the most generalized ElementsKind subclass. |
1784 return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, mode); | 1793 return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, mode); |
1785 } | 1794 } |
1786 } | 1795 } |
1787 return obj->GetHeap()->true_value(); | 1796 return isolate->factory()->true_value(); |
1788 } | 1797 } |
1789 | 1798 |
1790 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, | 1799 MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from, |
1791 uint32_t from_start, | 1800 uint32_t from_start, |
1792 FixedArrayBase* to, | 1801 FixedArrayBase* to, |
1793 ElementsKind from_kind, | 1802 ElementsKind from_kind, |
1794 uint32_t to_start, | 1803 uint32_t to_start, |
1795 int packed_size, | 1804 int packed_size, |
1796 int copy_size) { | 1805 int copy_size) { |
1797 UNREACHABLE(); | 1806 UNREACHABLE(); |
(...skipping 22 matching lines...) Expand all Loading... |
1820 return true; | 1829 return true; |
1821 } else { | 1830 } else { |
1822 FixedArrayBase* arguments = | 1831 FixedArrayBase* arguments = |
1823 FixedArrayBase::cast(FixedArray::cast(parameter_map)->get(1)); | 1832 FixedArrayBase::cast(FixedArray::cast(parameter_map)->get(1)); |
1824 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); | 1833 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
1825 return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); | 1834 return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); |
1826 } | 1835 } |
1827 } | 1836 } |
1828 | 1837 |
1829 private: | 1838 private: |
| 1839 // TODO(ishell): remove when all usages are handlified. |
1830 static Object* GetParameterMapArg(JSObject* holder, | 1840 static Object* GetParameterMapArg(JSObject* holder, |
1831 FixedArray* parameter_map, | 1841 FixedArray* parameter_map, |
1832 uint32_t key) { | 1842 uint32_t key) { |
1833 uint32_t length = holder->IsJSArray() | 1843 uint32_t length = holder->IsJSArray() |
1834 ? Smi::cast(JSArray::cast(holder)->length())->value() | 1844 ? Smi::cast(JSArray::cast(holder)->length())->value() |
1835 : parameter_map->length(); | 1845 : parameter_map->length(); |
1836 return key < (length - 2) | 1846 return key < (length - 2) |
1837 ? parameter_map->get(key + 2) | 1847 ? parameter_map->get(key + 2) |
1838 : parameter_map->GetHeap()->the_hole_value(); | 1848 : parameter_map->GetHeap()->the_hole_value(); |
1839 } | 1849 } |
| 1850 |
| 1851 static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, |
| 1852 Handle<FixedArray> parameter_map, |
| 1853 uint32_t key) { |
| 1854 Isolate* isolate = holder->GetIsolate(); |
| 1855 uint32_t length = holder->IsJSArray() |
| 1856 ? Smi::cast(Handle<JSArray>::cast(holder)->length())->value() |
| 1857 : parameter_map->length(); |
| 1858 return key < (length - 2) |
| 1859 ? handle(parameter_map->get(key + 2), isolate) |
| 1860 : Handle<Object>::cast(isolate->factory()->the_hole_value()); |
| 1861 } |
1840 }; | 1862 }; |
1841 | 1863 |
1842 | 1864 |
1843 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { | 1865 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { |
1844 return elements_accessors_[ElementsKindForArray(array)]; | 1866 return elements_accessors_[ElementsKindForArray(array)]; |
1845 } | 1867 } |
1846 | 1868 |
1847 | 1869 |
1848 void ElementsAccessor::InitializeOncePerProcess() { | 1870 void ElementsAccessor::InitializeOncePerProcess() { |
1849 static ElementsAccessor* accessor_array[] = { | 1871 static ElementsAccessor* accessor_array[] = { |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2021 UNREACHABLE(); | 2043 UNREACHABLE(); |
2022 break; | 2044 break; |
2023 } | 2045 } |
2024 | 2046 |
2025 array->set_elements(*elms); | 2047 array->set_elements(*elms); |
2026 array->set_length(Smi::FromInt(number_of_elements)); | 2048 array->set_length(Smi::FromInt(number_of_elements)); |
2027 return array; | 2049 return array; |
2028 } | 2050 } |
2029 | 2051 |
2030 } } // namespace v8::internal | 2052 } } // namespace v8::internal |
OLD | NEW |