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/isolate-inl.h" |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
482 Handle<Object> element_k; | 482 Handle<Object> element_k; |
483 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k, | 483 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k, |
484 Object::GetProperty(&it), Nothing<bool>()); | 484 Object::GetProperty(&it), Nothing<bool>()); |
485 | 485 |
486 if (value->SameValueZero(*element_k)) return Just(true); | 486 if (value->SameValueZero(*element_k)) return Just(true); |
487 } | 487 } |
488 | 488 |
489 return Just(false); | 489 return Just(false); |
490 } | 490 } |
491 | 491 |
492 static Maybe<int64_t> IndexOfValueSlowPath(Isolate* isolate, | |
493 Handle<JSObject> receiver, | |
494 Handle<Object> value, | |
495 uint32_t start_from, | |
496 uint32_t length) { | |
497 for (uint32_t k = start_from; k < length; ++k) { | |
498 LookupIterator it(isolate, receiver, k); | |
499 if (!it.IsFound()) { | |
500 continue; | |
501 } | |
502 Handle<Object> element_k; | |
503 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
504 isolate, element_k, Object::GetProperty(&it), Nothing<int64_t>()); | |
505 | |
506 if (value->StrictEquals(*element_k)) return Just<int64_t>(k); | |
507 } | |
508 | |
509 return Just<int64_t>(-1); | |
510 } | |
511 | |
492 // Base class for element handler implementations. Contains the | 512 // Base class for element handler implementations. Contains the |
493 // the common logic for objects with different ElementsKinds. | 513 // the common logic for objects with different ElementsKinds. |
494 // Subclasses must specialize method for which the element | 514 // Subclasses must specialize method for which the element |
495 // implementation differs from the base class implementation. | 515 // implementation differs from the base class implementation. |
496 // | 516 // |
497 // This class is intended to be used in the following way: | 517 // This class is intended to be used in the following way: |
498 // | 518 // |
499 // class SomeElementsAccessor : | 519 // class SomeElementsAccessor : |
500 // public ElementsAccessorBase<SomeElementsAccessor, | 520 // public ElementsAccessorBase<SomeElementsAccessor, |
501 // BackingStoreClass> { | 521 // BackingStoreClass> { |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1116 return IncludesValueSlowPath(isolate, receiver, value, start_from, length); | 1136 return IncludesValueSlowPath(isolate, receiver, value, start_from, length); |
1117 } | 1137 } |
1118 | 1138 |
1119 Maybe<bool> IncludesValue(Isolate* isolate, Handle<JSObject> receiver, | 1139 Maybe<bool> IncludesValue(Isolate* isolate, Handle<JSObject> receiver, |
1120 Handle<Object> value, uint32_t start_from, | 1140 Handle<Object> value, uint32_t start_from, |
1121 uint32_t length) final { | 1141 uint32_t length) final { |
1122 return Subclass::IncludesValueImpl(isolate, receiver, value, start_from, | 1142 return Subclass::IncludesValueImpl(isolate, receiver, value, start_from, |
1123 length); | 1143 length); |
1124 } | 1144 } |
1125 | 1145 |
1146 static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, | |
1147 Handle<JSObject> receiver, | |
1148 Handle<Object> value, | |
1149 uint32_t start_from, uint32_t length) { | |
1150 return IndexOfValueSlowPath(isolate, receiver, value, start_from, length); | |
1151 } | |
1152 | |
1153 Maybe<int64_t> IndexOfValue(Isolate* isolate, Handle<JSObject> receiver, | |
1154 Handle<Object> value, uint32_t start_from, | |
1155 uint32_t length) final { | |
1156 return Subclass::IndexOfValueImpl(isolate, receiver, value, start_from, | |
1157 length); | |
1158 } | |
1159 | |
1126 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, | 1160 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
1127 uint32_t entry) { | 1161 uint32_t entry) { |
1128 return entry; | 1162 return entry; |
1129 } | 1163 } |
1130 | 1164 |
1131 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 1165 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
1132 FixedArrayBase* backing_store, | 1166 FixedArrayBase* backing_store, |
1133 uint32_t index, PropertyFilter filter) { | 1167 uint32_t index, PropertyFilter filter) { |
1134 if (IsHoleyElementsKind(kind())) { | 1168 if (IsHoleyElementsKind(kind())) { |
1135 return index < Subclass::GetCapacityImpl(holder, backing_store) && | 1169 return index < Subclass::GetCapacityImpl(holder, backing_store) && |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1564 length); | 1598 length); |
1565 } | 1599 } |
1566 dictionary = handle( | 1600 dictionary = handle( |
1567 SeededNumberDictionary::cast(receiver->elements()), isolate); | 1601 SeededNumberDictionary::cast(receiver->elements()), isolate); |
1568 break; | 1602 break; |
1569 } | 1603 } |
1570 } | 1604 } |
1571 } | 1605 } |
1572 return Just(false); | 1606 return Just(false); |
1573 } | 1607 } |
1608 | |
1609 static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, | |
1610 Handle<JSObject> receiver, | |
1611 Handle<Object> value, | |
1612 uint32_t start_from, uint32_t length) { | |
1613 DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); | |
1614 | |
1615 Handle<SeededNumberDictionary> dictionary( | |
1616 SeededNumberDictionary::cast(receiver->elements()), isolate); | |
1617 // Iterate through entire range, as accessing elements out of order is | |
1618 // observable. | |
1619 for (uint32_t k = start_from; k < length; ++k) { | |
1620 int entry = dictionary->FindEntry(k); | |
1621 if (entry == SeededNumberDictionary::kNotFound) { | |
1622 continue; | |
1623 } | |
1624 | |
1625 PropertyDetails details = GetDetailsImpl(*dictionary, entry); | |
1626 switch (details.kind()) { | |
1627 case kData: { | |
1628 Object* element_k = dictionary->ValueAt(entry); | |
1629 if (value->StrictEquals(element_k)) { | |
1630 return Just<int64_t>(k); | |
1631 } | |
1632 break; | |
1633 } | |
1634 case kAccessor: { | |
1635 LookupIterator it(isolate, receiver, k, | |
1636 LookupIterator::OWN_SKIP_INTERCEPTOR); | |
1637 DCHECK(it.IsFound()); | |
1638 DCHECK_EQ(it.state(), LookupIterator::ACCESSOR); | |
1639 Handle<Object> element_k; | |
1640 | |
1641 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | |
1642 isolate, element_k, JSObject::GetPropertyWithAccessor(&it), | |
1643 Nothing<int64_t>()); | |
1644 | |
1645 if (value->StrictEquals(*element_k)) return Just<int64_t>(k); | |
1646 | |
1647 // Bailout to slow path if elements on prototype changed. | |
1648 if (!JSObject::PrototypeHasNoElements(isolate, *receiver)) { | |
1649 return IndexOfValueSlowPath(isolate, receiver, value, k + 1, | |
1650 length); | |
1651 } | |
1652 | |
1653 // Continue if elements unchanged. | |
1654 if (*dictionary == receiver->elements()) continue; | |
1655 | |
1656 // Otherwise, bailout or update elements. | |
1657 if (receiver->GetElementsKind() != DICTIONARY_ELEMENTS) { | |
1658 // Otherwise, switch to slow path. | |
1659 return IndexOfValueSlowPath(isolate, receiver, value, k + 1, | |
1660 length); | |
1661 } | |
1662 dictionary = handle( | |
1663 SeededNumberDictionary::cast(receiver->elements()), isolate); | |
1664 break; | |
1665 } | |
1666 } | |
1667 } | |
1668 return Just<int64_t>(-1); | |
1669 } | |
1574 }; | 1670 }; |
1575 | 1671 |
1576 | 1672 |
1577 // Super class for all fast element arrays. | 1673 // Super class for all fast element arrays. |
1578 template <typename Subclass, typename KindTraits> | 1674 template <typename Subclass, typename KindTraits> |
1579 class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { | 1675 class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { |
1580 public: | 1676 public: |
1581 explicit FastElementsAccessor(const char* name) | 1677 explicit FastElementsAccessor(const char* name) |
1582 : ElementsAccessorBase<Subclass, KindTraits>(name) {} | 1678 : ElementsAccessorBase<Subclass, KindTraits>(name) {} |
1583 | 1679 |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2074 | 2170 |
2075 for (uint32_t k = start_from; k < length; ++k) { | 2171 for (uint32_t k = start_from; k < length; ++k) { |
2076 if (elements->get(k)->IsNaN()) return Just(true); | 2172 if (elements->get(k)->IsNaN()) return Just(true); |
2077 } | 2173 } |
2078 return Just(false); | 2174 return Just(false); |
2079 } | 2175 } |
2080 } | 2176 } |
2081 } | 2177 } |
2082 } | 2178 } |
2083 | 2179 |
2180 static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, | |
2181 Handle<JSObject> receiver, | |
2182 Handle<Object> search_value, | |
2183 uint32_t start_from, uint32_t length) { | |
2184 DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); | |
2185 DisallowHeapAllocation no_gc; | |
2186 FixedArrayBase* elements_base = receiver->elements(); | |
2187 Object* the_hole = isolate->heap()->the_hole_value(); | |
2188 Object* undefined = isolate->heap()->undefined_value(); | |
2189 Object* value = *search_value; | |
2190 | |
2191 if (start_from >= length) return Just<int64_t>(-1); | |
2192 | |
2193 length = std::min(static_cast<uint32_t>(elements_base->length()), length); | |
2194 | |
2195 if (!value->IsNumber()) { | |
Jakob Kummerow
2016/08/19 09:49:56
Try this simplification:
// Only FAST_{,HOLEY
mattloring
2016/08/19 17:22:33
I did not observe a performance difference so I've
Jakob Kummerow
2016/08/22 09:54:10
FixedArray::cast(receiver->elements()) only works
mattloring
2016/08/22 17:07:03
Ah ok, that makes sense. Thanks!
| |
2196 if (value == undefined) { | |
2197 // Only FAST_ELEMENTS and FAST_HOLEY_ELEMENTS can have | |
2198 // `undefined` as a value. | |
2199 if (!IsFastElementsKind(Subclass::kind()) && | |
Jakob Kummerow
2016/08/19 09:49:56
This is the FastElementsAccessor. All Subclass::ki
mattloring
2016/08/19 17:22:33
Thank you for the clarification. This check is no
| |
2200 !IsFastHoleyElementsKind(Subclass::kind())) { | |
2201 return Just<int64_t>(-1); | |
2202 } | |
2203 | |
2204 FixedArray* elements = FixedArray::cast(receiver->elements()); | |
2205 | |
2206 for (uint32_t k = start_from; k < length; ++k) { | |
2207 if (elements->get(k) == undefined) { | |
2208 return Just<int64_t>(k); | |
2209 } | |
2210 } | |
2211 return Just<int64_t>(-1); | |
2212 } else { | |
2213 // Search for non-number, non-Undefined value with either | |
2214 // FAST_ELEMENTS or FAST_HOLEY_ELEMENTS. | |
2215 DCHECK(IsFastObjectElementsKind(Subclass::kind())); | |
2216 FixedArray* elements = FixedArray::cast(receiver->elements()); | |
2217 | |
2218 for (uint32_t k = start_from; k < length; ++k) { | |
2219 Object* element_k = elements->get(k); | |
2220 if (element_k == the_hole) { | |
2221 continue; | |
2222 } | |
2223 | |
2224 if (value->StrictEquals(element_k)) { | |
2225 return Just<int64_t>(k); | |
2226 } | |
2227 } | |
2228 return Just<int64_t>(-1); | |
2229 } | |
2230 } else { | |
2231 if (value->IsNaN()) { | |
2232 return Just<int64_t>(-1); | |
2233 } | |
2234 double search_value = value->Number(); | |
2235 FixedArray* elements = FixedArray::cast(receiver->elements()); | |
2236 | |
2237 for (uint32_t k = start_from; k < length; ++k) { | |
2238 Object* element_k = elements->get(k); | |
2239 if (element_k->IsNumber() && element_k->Number() == search_value) { | |
2240 return Just<int64_t>(k); | |
2241 } | |
2242 } | |
2243 return Just<int64_t>(-1); | |
2244 } | |
2245 } | |
2246 | |
2084 private: | 2247 private: |
2085 // SpliceShrinkStep might modify the backing_store. | 2248 // SpliceShrinkStep might modify the backing_store. |
2086 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, | 2249 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, |
2087 Handle<FixedArrayBase> backing_store, | 2250 Handle<FixedArrayBase> backing_store, |
2088 uint32_t start, uint32_t delete_count, | 2251 uint32_t start, uint32_t delete_count, |
2089 uint32_t add_count, uint32_t len, | 2252 uint32_t add_count, uint32_t len, |
2090 uint32_t new_length) { | 2253 uint32_t new_length) { |
2091 const int move_left_count = len - delete_count - start; | 2254 const int move_left_count = len - delete_count - start; |
2092 const int move_left_dst_index = start + add_count; | 2255 const int move_left_dst_index = start + add_count; |
2093 Subclass::MoveElements(isolate, receiver, backing_store, | 2256 Subclass::MoveElements(isolate, receiver, backing_store, |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2391 case NO_ELEMENTS: | 2554 case NO_ELEMENTS: |
2392 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS: | 2555 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS: |
2393 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 2556 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
2394 #undef TYPED_ARRAY_CASE | 2557 #undef TYPED_ARRAY_CASE |
2395 // This function is currently only used for JSArrays with non-zero | 2558 // This function is currently only used for JSArrays with non-zero |
2396 // length. | 2559 // length. |
2397 UNREACHABLE(); | 2560 UNREACHABLE(); |
2398 break; | 2561 break; |
2399 } | 2562 } |
2400 } | 2563 } |
2564 | |
2565 static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, | |
2566 Handle<JSObject> receiver, | |
2567 Handle<Object> search_value, | |
2568 uint32_t start_from, uint32_t length) { | |
2569 DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); | |
2570 DisallowHeapAllocation no_gc; | |
2571 FixedArrayBase* elements_base = receiver->elements(); | |
2572 Object* value = *search_value; | |
2573 | |
2574 if (start_from >= length) return Just<int64_t>(-1); | |
2575 | |
2576 length = std::min(static_cast<uint32_t>(elements_base->length()), length); | |
2577 | |
2578 if (!value->IsNumber()) { | |
2579 return Just<int64_t>(-1); | |
2580 } | |
2581 if (value->IsNaN()) { | |
2582 return Just<int64_t>(-1); | |
2583 } | |
2584 double numeric_search_value = value->Number(); | |
2585 FixedDoubleArray* elements = FixedDoubleArray::cast(receiver->elements()); | |
2586 | |
2587 for (uint32_t k = start_from; k < length; ++k) { | |
2588 if (elements->is_the_hole(k)) { | |
Jakob Kummerow
2016/08/19 09:49:56
(Just for the record: if everything does fit on on
mattloring
2016/08/19 17:22:33
Ack. Thanks for clarifying.
| |
2589 continue; | |
2590 } | |
2591 if (elements->get_scalar(k) == numeric_search_value) { | |
2592 return Just<int64_t>(k); | |
2593 } | |
2594 } | |
2595 return Just<int64_t>(-1); | |
2596 } | |
2401 }; | 2597 }; |
2402 | 2598 |
2403 | 2599 |
2404 class FastPackedDoubleElementsAccessor | 2600 class FastPackedDoubleElementsAccessor |
2405 : public FastDoubleElementsAccessor< | 2601 : public FastDoubleElementsAccessor< |
2406 FastPackedDoubleElementsAccessor, | 2602 FastPackedDoubleElementsAccessor, |
2407 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > { | 2603 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > { |
2408 public: | 2604 public: |
2409 explicit FastPackedDoubleElementsAccessor(const char* name) | 2605 explicit FastPackedDoubleElementsAccessor(const char* name) |
2410 : FastDoubleElementsAccessor< | 2606 : FastDoubleElementsAccessor< |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2584 } | 2780 } |
2585 return Just(false); | 2781 return Just(false); |
2586 } else { | 2782 } else { |
2587 for (uint32_t k = start_from; k < length; ++k) { | 2783 for (uint32_t k = start_from; k < length; ++k) { |
2588 double element_k = elements->get_scalar(k); | 2784 double element_k = elements->get_scalar(k); |
2589 if (std::isnan(element_k)) return Just(true); | 2785 if (std::isnan(element_k)) return Just(true); |
2590 } | 2786 } |
2591 return Just(false); | 2787 return Just(false); |
2592 } | 2788 } |
2593 } | 2789 } |
2790 | |
2791 static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, | |
2792 Handle<JSObject> receiver, | |
2793 Handle<Object> value, | |
2794 uint32_t start_from, uint32_t length) { | |
2795 DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); | |
2796 DisallowHeapAllocation no_gc; | |
2797 | |
2798 BackingStore* elements = BackingStore::cast(receiver->elements()); | |
2799 if (!value->IsNumber()) return Just<int64_t>(-1); | |
2800 | |
2801 double search_value = value->Number(); | |
2802 | |
2803 if (!std::isfinite(search_value)) { | |
2804 // Integral types cannot represent +Inf or NaN. | |
2805 if (AccessorClass::kind() < FLOAT32_ELEMENTS || | |
2806 AccessorClass::kind() > FLOAT64_ELEMENTS) { | |
2807 return Just<int64_t>(-1); | |
2808 } | |
2809 } else if (search_value < std::numeric_limits<ctype>::lowest() || | |
2810 search_value > std::numeric_limits<ctype>::max()) { | |
2811 // Return false if value can't be represented in this ElementsKind. | |
2812 return Just<int64_t>(-1); | |
2813 } | |
2814 | |
2815 // Prototype has no elements, and not searching for the hole --- limit | |
2816 // search to backing store length. | |
2817 if (static_cast<uint32_t>(elements->length()) < length) { | |
2818 length = elements->length(); | |
2819 } | |
2820 | |
2821 if (std::isnan(search_value)) { | |
2822 return Just<int64_t>(-1); | |
2823 } | |
2824 for (uint32_t k = start_from; k < length; ++k) { | |
2825 ctype element_k = elements->get_scalar(k); | |
2826 if (element_k == search_value) return Just<int64_t>(k); | |
Jakob Kummerow
2016/08/19 09:49:56
This still does an implicit cast to double, which
mattloring
2016/08/19 17:22:33
Done.
| |
2827 } | |
2828 return Just<int64_t>(-1); | |
2829 } | |
2594 }; | 2830 }; |
2595 | 2831 |
2596 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ | 2832 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
2597 typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \ | 2833 typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \ |
2598 Fixed##Type##ElementsAccessor; | 2834 Fixed##Type##ElementsAccessor; |
2599 | 2835 |
2600 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) | 2836 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) |
2601 #undef FIXED_ELEMENTS_ACCESSOR | 2837 #undef FIXED_ELEMENTS_ACCESSOR |
2602 | 2838 |
2603 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits> | 2839 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits> |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2862 if (object->map() != *original_map) { | 3098 if (object->map() != *original_map) { |
2863 // Some mutation occurred in accessor. Abort "fast" path | 3099 // Some mutation occurred in accessor. Abort "fast" path |
2864 return IncludesValueSlowPath(isolate, object, value, k + 1, length); | 3100 return IncludesValueSlowPath(isolate, object, value, k + 1, length); |
2865 } | 3101 } |
2866 } else if (value->SameValueZero(*element_k)) { | 3102 } else if (value->SameValueZero(*element_k)) { |
2867 return Just(true); | 3103 return Just(true); |
2868 } | 3104 } |
2869 } | 3105 } |
2870 return Just(false); | 3106 return Just(false); |
2871 } | 3107 } |
3108 | |
3109 static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate, | |
3110 Handle<JSObject> object, | |
3111 Handle<Object> value, | |
3112 uint32_t start_from, uint32_t length) { | |
3113 DCHECK(JSObject::PrototypeHasNoElements(isolate, *object)); | |
3114 Handle<Map> original_map = handle(object->map(), isolate); | |
3115 FixedArray* parameter_map = FixedArray::cast(object->elements()); | |
3116 | |
3117 for (uint32_t k = start_from; k < length; ++k) { | |
3118 uint32_t entry = | |
3119 GetEntryForIndexImpl(*object, parameter_map, k, ALL_PROPERTIES); | |
3120 if (entry == kMaxUInt32) { | |
3121 continue; | |
3122 } | |
3123 | |
3124 Handle<Object> element_k = GetImpl(parameter_map, entry); | |
3125 | |
3126 if (element_k->IsAccessorPair()) { | |
3127 LookupIterator it(isolate, object, k, LookupIterator::OWN); | |
3128 DCHECK(it.IsFound()); | |
3129 DCHECK_EQ(it.state(), LookupIterator::ACCESSOR); | |
3130 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k, | |
3131 Object::GetPropertyWithAccessor(&it), | |
3132 Nothing<int64_t>()); | |
3133 | |
3134 if (value->StrictEquals(*element_k)) { | |
3135 return Just<int64_t>(k); | |
3136 } | |
3137 | |
3138 if (object->map() != *original_map) { | |
3139 // Some mutation occurred in accessor. Abort "fast" path. | |
3140 return IndexOfValueSlowPath(isolate, object, value, k + 1, length); | |
3141 } | |
3142 } else if (value->StrictEquals(*element_k)) { | |
3143 return Just<int64_t>(k); | |
3144 } | |
3145 } | |
3146 return Just<int64_t>(-1); | |
3147 } | |
2872 }; | 3148 }; |
2873 | 3149 |
2874 | 3150 |
2875 class SlowSloppyArgumentsElementsAccessor | 3151 class SlowSloppyArgumentsElementsAccessor |
2876 : public SloppyArgumentsElementsAccessor< | 3152 : public SloppyArgumentsElementsAccessor< |
2877 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, | 3153 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, |
2878 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > { | 3154 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > { |
2879 public: | 3155 public: |
2880 explicit SlowSloppyArgumentsElementsAccessor(const char* name) | 3156 explicit SlowSloppyArgumentsElementsAccessor(const char* name) |
2881 : SloppyArgumentsElementsAccessor< | 3157 : SloppyArgumentsElementsAccessor< |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3469 insertion_index += len; | 3745 insertion_index += len; |
3470 } | 3746 } |
3471 | 3747 |
3472 DCHECK_EQ(insertion_index, result_len); | 3748 DCHECK_EQ(insertion_index, result_len); |
3473 return result_array; | 3749 return result_array; |
3474 } | 3750 } |
3475 | 3751 |
3476 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3752 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
3477 } // namespace internal | 3753 } // namespace internal |
3478 } // namespace v8 | 3754 } // namespace v8 |
OLD | NEW |