| OLD | NEW |
| 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/elements.h" | 5 #include "src/elements.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/factory.h" | 9 #include "src/factory.h" |
| 10 #include "src/isolate-inl.h" |
| 10 #include "src/messages.h" | 11 #include "src/messages.h" |
| 11 #include "src/objects-inl.h" | 12 #include "src/objects-inl.h" |
| 12 #include "src/utils.h" | 13 #include "src/utils.h" |
| 13 | 14 |
| 14 // Each concrete ElementsAccessor can handle exactly one ElementsKind, | 15 // Each concrete ElementsAccessor can handle exactly one ElementsKind, |
| 15 // several abstract ElementsAccessor classes are used to allow sharing | 16 // several abstract ElementsAccessor classes are used to allow sharing |
| 16 // common code. | 17 // common code. |
| 17 // | 18 // |
| 18 // Inheritance hierarchy: | 19 // Inheritance hierarchy: |
| 19 // - ElementsAccessorBase (abstract) | 20 // - ElementsAccessorBase (abstract) |
| (...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 // intentionally to avoid ArrayConcat() builtin performance degradation. | 829 // intentionally to avoid ArrayConcat() builtin performance degradation. |
| 829 // | 830 // |
| 830 // Details: The idea is that allocations actually happen only in case of | 831 // Details: The idea is that allocations actually happen only in case of |
| 831 // copying from object with fast double elements to object with object | 832 // copying from object with fast double elements to object with object |
| 832 // elements. In all the other cases there are no allocations performed and | 833 // elements. In all the other cases there are no allocations performed and |
| 833 // handle creation causes noticeable performance degradation of the builtin. | 834 // handle creation causes noticeable performance degradation of the builtin. |
| 834 ElementsAccessorSubclass::CopyElementsImpl( | 835 ElementsAccessorSubclass::CopyElementsImpl( |
| 835 from, from_start, *to, from_kind, to_start, packed_size, copy_size); | 836 from, from_start, *to, from_kind, to_start, packed_size, copy_size); |
| 836 } | 837 } |
| 837 | 838 |
| 839 Maybe<bool> CollectValuesOrEntries(Isolate* isolate, Handle<JSObject> object, |
| 840 Handle<FixedArray> values_or_entries, |
| 841 bool get_entries, int* nof_items, |
| 842 PropertyFilter filter) { |
| 843 return ElementsAccessorSubclass::CollectValuesOrEntriesImpl( |
| 844 isolate, object, values_or_entries, get_entries, nof_items, filter); |
| 845 } |
| 846 |
| 847 static Maybe<bool> CollectValuesOrEntriesImpl( |
| 848 Isolate* isolate, Handle<JSObject> object, |
| 849 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
| 850 PropertyFilter filter) { |
| 851 int count = 0; |
| 852 KeyAccumulator accumulator(isolate, OWN_ONLY, ALL_PROPERTIES); |
| 853 accumulator.NextPrototype(); |
| 854 ElementsAccessorSubclass::CollectElementIndicesImpl( |
| 855 object, handle(object->elements(), isolate), &accumulator, kMaxUInt32, |
| 856 ALL_PROPERTIES, 0); |
| 857 Handle<FixedArray> keys = accumulator.GetKeys(); |
| 858 |
| 859 for (int i = 0; i < keys->length(); ++i) { |
| 860 Handle<Object> key(keys->get(i), isolate); |
| 861 Handle<Object> value; |
| 862 uint32_t index; |
| 863 if (!key->ToUint32(&index)) continue; |
| 864 |
| 865 uint32_t entry = ElementsAccessorSubclass::GetEntryForIndexImpl( |
| 866 *object, object->elements(), index, filter); |
| 867 if (entry == kMaxUInt32) continue; |
| 868 |
| 869 PropertyDetails details = |
| 870 ElementsAccessorSubclass::GetDetailsImpl(*object, entry); |
| 871 |
| 872 if (details.kind() == kData) { |
| 873 value = ElementsAccessorSubclass::GetImpl(object, entry); |
| 874 } else { |
| 875 LookupIterator it(isolate, object, index, LookupIterator::OWN); |
| 876 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 877 isolate, value, Object::GetProperty(&it), Nothing<bool>()); |
| 878 } |
| 879 if (get_entries) { |
| 880 value = MakeEntryPair(isolate, index, value); |
| 881 } |
| 882 values_or_entries->set(count++, *value); |
| 883 } |
| 884 |
| 885 *nof_items = count; |
| 886 return Just(true); |
| 887 } |
| 888 |
| 838 void CollectElementIndices(Handle<JSObject> object, | 889 void CollectElementIndices(Handle<JSObject> object, |
| 839 Handle<FixedArrayBase> backing_store, | 890 Handle<FixedArrayBase> backing_store, |
| 840 KeyAccumulator* keys, uint32_t range, | 891 KeyAccumulator* keys, uint32_t range, |
| 841 PropertyFilter filter, uint32_t offset) final { | 892 PropertyFilter filter, uint32_t offset) final { |
| 842 ElementsAccessorSubclass::CollectElementIndicesImpl( | 893 ElementsAccessorSubclass::CollectElementIndicesImpl( |
| 843 object, backing_store, keys, range, filter, offset); | 894 object, backing_store, keys, range, filter, offset); |
| 844 } | 895 } |
| 845 | 896 |
| 846 static void CollectElementIndicesImpl(Handle<JSObject> object, | 897 static void CollectElementIndicesImpl(Handle<JSObject> object, |
| 847 Handle<FixedArrayBase> backing_store, | 898 Handle<FixedArrayBase> backing_store, |
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1538 // Copy over the arguments. | 1589 // Copy over the arguments. |
| 1539 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_count, | 1590 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_count, |
| 1540 3, start); | 1591 3, start); |
| 1541 | 1592 |
| 1542 receiver->set_length(Smi::FromInt(new_length)); | 1593 receiver->set_length(Smi::FromInt(new_length)); |
| 1543 FastElementsAccessorSubclass::TryTransitionResultArrayToPacked( | 1594 FastElementsAccessorSubclass::TryTransitionResultArrayToPacked( |
| 1544 deleted_elements); | 1595 deleted_elements); |
| 1545 return deleted_elements; | 1596 return deleted_elements; |
| 1546 } | 1597 } |
| 1547 | 1598 |
| 1599 static Maybe<bool> CollectValuesOrEntriesImpl( |
| 1600 Isolate* isolate, Handle<JSObject> object, |
| 1601 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
| 1602 PropertyFilter filter) { |
| 1603 int count = 0; |
| 1604 uint32_t length = object->elements()->length(); |
| 1605 for (uint32_t index = 0; index < length; ++index) { |
| 1606 if (!HasEntryImpl(object->elements(), index)) continue; |
| 1607 Handle<Object> value = |
| 1608 FastElementsAccessorSubclass::GetImpl(object->elements(), index); |
| 1609 if (get_entries) { |
| 1610 value = MakeEntryPair(isolate, index, value); |
| 1611 } |
| 1612 values_or_entries->set(count++, *value); |
| 1613 } |
| 1614 *nof_items = count; |
| 1615 return Just(true); |
| 1616 } |
| 1617 |
| 1548 private: | 1618 private: |
| 1549 // SpliceShrinkStep might modify the backing_store. | 1619 // SpliceShrinkStep might modify the backing_store. |
| 1550 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, | 1620 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, |
| 1551 Handle<FixedArrayBase> backing_store, | 1621 Handle<FixedArrayBase> backing_store, |
| 1552 uint32_t start, uint32_t delete_count, | 1622 uint32_t start, uint32_t delete_count, |
| 1553 uint32_t add_count, uint32_t len, | 1623 uint32_t add_count, uint32_t len, |
| 1554 uint32_t new_length) { | 1624 uint32_t new_length) { |
| 1555 const int move_left_count = len - delete_count - start; | 1625 const int move_left_count = len - delete_count - start; |
| 1556 const int move_left_dst_index = start + add_count; | 1626 const int move_left_dst_index = start + add_count; |
| 1557 FastElementsAccessorSubclass::MoveElements( | 1627 FastElementsAccessorSubclass::MoveElements( |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2033 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 2103 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
| 2034 KeyAccumulator* accumulator, | 2104 KeyAccumulator* accumulator, |
| 2035 AddKeyConversion convert) { | 2105 AddKeyConversion convert) { |
| 2036 Handle<FixedArrayBase> elements(receiver->elements()); | 2106 Handle<FixedArrayBase> elements(receiver->elements()); |
| 2037 uint32_t length = AccessorClass::GetCapacityImpl(*receiver, *elements); | 2107 uint32_t length = AccessorClass::GetCapacityImpl(*receiver, *elements); |
| 2038 for (uint32_t i = 0; i < length; i++) { | 2108 for (uint32_t i = 0; i < length; i++) { |
| 2039 Handle<Object> value = AccessorClass::GetImpl(*elements, i); | 2109 Handle<Object> value = AccessorClass::GetImpl(*elements, i); |
| 2040 accumulator->AddKey(value, convert); | 2110 accumulator->AddKey(value, convert); |
| 2041 } | 2111 } |
| 2042 } | 2112 } |
| 2113 |
| 2114 static Maybe<bool> CollectValuesOrEntriesImpl( |
| 2115 Isolate* isolate, Handle<JSObject> object, |
| 2116 Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
| 2117 PropertyFilter filter) { |
| 2118 int count = 0; |
| 2119 if ((filter & ONLY_CONFIGURABLE) == 0) { |
| 2120 Handle<FixedArrayBase> elements(object->elements()); |
| 2121 uint32_t length = AccessorClass::GetCapacityImpl(*object, *elements); |
| 2122 for (uint32_t index = 0; index < length; ++index) { |
| 2123 Handle<Object> value = AccessorClass::GetImpl(*elements, index); |
| 2124 if (get_entries) { |
| 2125 value = MakeEntryPair(isolate, index, value); |
| 2126 } |
| 2127 values_or_entries->set(count++, *value); |
| 2128 } |
| 2129 } |
| 2130 *nof_items = count; |
| 2131 return Just(true); |
| 2132 } |
| 2043 }; | 2133 }; |
| 2044 | 2134 |
| 2045 | 2135 |
| 2046 | 2136 |
| 2047 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ | 2137 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
| 2048 typedef TypedElementsAccessor<TYPE##_ELEMENTS > \ | 2138 typedef TypedElementsAccessor<TYPE##_ELEMENTS > \ |
| 2049 Fixed##Type##ElementsAccessor; | 2139 Fixed##Type##ElementsAccessor; |
| 2050 | 2140 |
| 2051 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) | 2141 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) |
| 2052 #undef FIXED_ELEMENTS_ACCESSOR | 2142 #undef FIXED_ELEMENTS_ACCESSOR |
| (...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2823 } | 2913 } |
| 2824 } | 2914 } |
| 2825 | 2915 |
| 2826 DCHECK(j == result_len); | 2916 DCHECK(j == result_len); |
| 2827 return result_array; | 2917 return result_array; |
| 2828 } | 2918 } |
| 2829 | 2919 |
| 2830 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2920 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
| 2831 } // namespace internal | 2921 } // namespace internal |
| 2832 } // namespace v8 | 2922 } // namespace v8 |
| OLD | NEW |