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 |