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

Side by Side Diff: src/elements.cc

Issue 2202163002: Revert of [builtins] implement Array.prototype.includes in TurboFan (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 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 | « src/elements.h ('k') | src/factory.h » ('j') | 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/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 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 } cmp; 461 } cmp;
462 Object** start = 462 Object** start =
463 reinterpret_cast<Object**>(indices->GetFirstElementAddress()); 463 reinterpret_cast<Object**>(indices->GetFirstElementAddress());
464 std::sort(start, start + sort_size, cmp); 464 std::sort(start, start + sort_size, cmp);
465 if (write_barrier_mode != SKIP_WRITE_BARRIER) { 465 if (write_barrier_mode != SKIP_WRITE_BARRIER) {
466 FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(indices->GetIsolate()->heap(), *indices, 466 FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(indices->GetIsolate()->heap(), *indices,
467 0, sort_size); 467 0, sort_size);
468 } 468 }
469 } 469 }
470 470
471 static Maybe<bool> IncludesValueSlowPath(Isolate* isolate,
472 Handle<JSObject> receiver,
473 Handle<Object> value,
474 uint32_t start_from, uint32_t length) {
475 bool search_for_hole = value->IsUndefined(isolate);
476 for (uint32_t k = start_from; k < length; ++k) {
477 LookupIterator it(isolate, receiver, k);
478 if (!it.IsFound()) {
479 if (search_for_hole) return Just(true);
480 continue;
481 }
482 Handle<Object> element_k;
483 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k,
484 Object::GetProperty(&it), Nothing<bool>());
485
486 if (value->SameValueZero(*element_k)) return Just(true);
487 }
488
489 return Just(false);
490 }
491
492 // Base class for element handler implementations. Contains the 471 // Base class for element handler implementations. Contains the
493 // the common logic for objects with different ElementsKinds. 472 // the common logic for objects with different ElementsKinds.
494 // Subclasses must specialize method for which the element 473 // Subclasses must specialize method for which the element
495 // implementation differs from the base class implementation. 474 // implementation differs from the base class implementation.
496 // 475 //
497 // This class is intended to be used in the following way: 476 // This class is intended to be used in the following way:
498 // 477 //
499 // class SomeElementsAccessor : 478 // class SomeElementsAccessor :
500 // public ElementsAccessorBase<SomeElementsAccessor, 479 // public ElementsAccessorBase<SomeElementsAccessor,
501 // BackingStoreClass> { 480 // BackingStoreClass> {
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 1077
1099 static uint32_t GetCapacityImpl(JSObject* holder, 1078 static uint32_t GetCapacityImpl(JSObject* holder,
1100 FixedArrayBase* backing_store) { 1079 FixedArrayBase* backing_store) {
1101 return backing_store->length(); 1080 return backing_store->length();
1102 } 1081 }
1103 1082
1104 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { 1083 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final {
1105 return Subclass::GetCapacityImpl(holder, backing_store); 1084 return Subclass::GetCapacityImpl(holder, backing_store);
1106 } 1085 }
1107 1086
1108 static Maybe<bool> IncludesValueImpl(Isolate* isolate,
1109 Handle<JSObject> receiver,
1110 Handle<Object> value,
1111 uint32_t start_from, uint32_t length) {
1112 return IncludesValueSlowPath(isolate, receiver, value, start_from, length);
1113 }
1114
1115 Maybe<bool> IncludesValue(Isolate* isolate, Handle<JSObject> receiver,
1116 Handle<Object> value, uint32_t start_from,
1117 uint32_t length) final {
1118 return Subclass::IncludesValueImpl(isolate, receiver, value, start_from,
1119 length);
1120 }
1121
1122 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, 1087 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store,
1123 uint32_t entry) { 1088 uint32_t entry) {
1124 return entry; 1089 return entry;
1125 } 1090 }
1126 1091
1127 static uint32_t GetEntryForIndexImpl(JSObject* holder, 1092 static uint32_t GetEntryForIndexImpl(JSObject* holder,
1128 FixedArrayBase* backing_store, 1093 FixedArrayBase* backing_store,
1129 uint32_t index, PropertyFilter filter) { 1094 uint32_t index, PropertyFilter filter) {
1130 if (IsHoleyElementsKind(kind())) { 1095 if (IsHoleyElementsKind(kind())) {
1131 return index < Subclass::GetCapacityImpl(holder, backing_store) && 1096 return index < Subclass::GetCapacityImpl(holder, backing_store) &&
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 if (k == *undefined) continue; 1413 if (k == *undefined) continue;
1449 if (k == *the_hole) continue; 1414 if (k == *the_hole) continue;
1450 if (dictionary->IsDeleted(i)) continue; 1415 if (dictionary->IsDeleted(i)) continue;
1451 Object* value = dictionary->ValueAt(i); 1416 Object* value = dictionary->ValueAt(i);
1452 DCHECK(!value->IsTheHole(isolate)); 1417 DCHECK(!value->IsTheHole(isolate));
1453 DCHECK(!value->IsAccessorPair()); 1418 DCHECK(!value->IsAccessorPair());
1454 DCHECK(!value->IsAccessorInfo()); 1419 DCHECK(!value->IsAccessorInfo());
1455 accumulator->AddKey(value, convert); 1420 accumulator->AddKey(value, convert);
1456 } 1421 }
1457 } 1422 }
1458
1459 static bool IncludesValueFastPath(Isolate* isolate, Handle<JSObject> receiver,
1460 Handle<Object> value, uint32_t start_from,
1461 uint32_t length, Maybe<bool>* result) {
1462 DisallowHeapAllocation no_gc;
1463 SeededNumberDictionary* dictionary =
1464 SeededNumberDictionary::cast(receiver->elements());
1465 int capacity = dictionary->Capacity();
1466 Object* the_hole = isolate->heap()->the_hole_value();
1467 Object* undefined = isolate->heap()->undefined_value();
1468
1469 // Scan for accessor properties. If accessors are present, then elements
1470 // must be accessed in order via the slow path.
1471 bool found = false;
1472 for (int i = 0; i < capacity; ++i) {
1473 Object* k = dictionary->KeyAt(i);
1474 if (k == the_hole) continue;
1475 if (k == undefined) continue;
1476
1477 uint32_t index;
1478 if (!k->ToArrayIndex(&index) || index < start_from || index >= length) {
1479 continue;
1480 }
1481
1482 if (dictionary->DetailsAt(i).type() == ACCESSOR_CONSTANT) {
1483 // Restart from beginning in slow path, otherwise we may observably
1484 // access getters out of order
1485 return false;
1486 } else if (!found) {
1487 Object* element_k = dictionary->ValueAt(i);
1488 if (value->SameValueZero(element_k)) found = true;
1489 }
1490 }
1491
1492 *result = Just(found);
1493 return true;
1494 }
1495
1496 static Maybe<bool> IncludesValueImpl(Isolate* isolate,
1497 Handle<JSObject> receiver,
1498 Handle<Object> value,
1499 uint32_t start_from, uint32_t length) {
1500 DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver));
1501 bool search_for_hole = value->IsUndefined(isolate);
1502
1503 if (!search_for_hole) {
1504 Maybe<bool> result = Nothing<bool>();
1505 if (DictionaryElementsAccessor::IncludesValueFastPath(
1506 isolate, receiver, value, start_from, length, &result)) {
1507 return result;
1508 }
1509 }
1510
1511 Handle<SeededNumberDictionary> dictionary(
1512 SeededNumberDictionary::cast(receiver->elements()), isolate);
1513 // Iterate through entire range, as accessing elements out of order is
1514 // observable
1515 for (uint32_t k = start_from; k < length; ++k) {
1516 int entry = dictionary->FindEntry(k);
1517 if (entry == SeededNumberDictionary::kNotFound) {
1518 if (search_for_hole) return Just(true);
1519 continue;
1520 }
1521
1522 PropertyDetails details = GetDetailsImpl(receiver->elements(), entry);
1523 switch (details.kind()) {
1524 case kData: {
1525 Object* element_k = dictionary->ValueAt(entry);
1526 if (value->SameValueZero(element_k)) return Just(true);
1527 break;
1528 }
1529 case kAccessor: {
1530 LookupIterator it(isolate, receiver, k,
1531 LookupIterator::OWN_SKIP_INTERCEPTOR);
1532 DCHECK(it.IsFound());
1533 DCHECK_EQ(it.state(), LookupIterator::ACCESSOR);
1534 Handle<Object> element_k;
1535
1536 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
1537 isolate, element_k, JSObject::GetPropertyWithAccessor(&it),
1538 Nothing<bool>());
1539
1540 if (value->SameValueZero(*element_k)) return Just(true);
1541
1542 // Some mutation to the prototype elements may have occurred in
1543 // accessor.
1544 if (!JSObject::PrototypeHasNoElements(isolate, *receiver)) {
1545 return IncludesValueSlowPath(isolate, receiver, value, k + 1,
1546 length);
1547 }
1548 break;
1549 }
1550 }
1551 }
1552 return Just(false);
1553 }
1554 }; 1423 };
1555 1424
1556 1425
1557 // Super class for all fast element arrays. 1426 // Super class for all fast element arrays.
1558 template <typename Subclass, typename KindTraits> 1427 template <typename Subclass, typename KindTraits>
1559 class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { 1428 class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
1560 public: 1429 public:
1561 explicit FastElementsAccessor(const char* name) 1430 explicit FastElementsAccessor(const char* name)
1562 : ElementsAccessorBase<Subclass, KindTraits>(name) {} 1431 : ElementsAccessorBase<Subclass, KindTraits>(name) {}
1563 1432
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1904 DisallowHeapAllocation no_gc; 1773 DisallowHeapAllocation no_gc;
1905 heap->MoveElements(FixedArray::cast(*dst_elms), dst_index, src_index, 1774 heap->MoveElements(FixedArray::cast(*dst_elms), dst_index, src_index,
1906 len); 1775 len);
1907 } 1776 }
1908 } 1777 }
1909 if (hole_start != hole_end) { 1778 if (hole_start != hole_end) {
1910 dst_elms->FillWithHoles(hole_start, hole_end); 1779 dst_elms->FillWithHoles(hole_start, hole_end);
1911 } 1780 }
1912 } 1781 }
1913 1782
1914 static Maybe<bool> IncludesValueImpl(Isolate* isolate,
1915 Handle<JSObject> receiver,
1916 Handle<Object> search_value,
1917 uint32_t start_from, uint32_t length) {
1918 DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver));
1919 DisallowHeapAllocation no_gc;
1920 FixedArrayBase* elements_base = receiver->elements();
1921 Object* the_hole = isolate->heap()->the_hole_value();
1922 Object* undefined = isolate->heap()->undefined_value();
1923 Object* value = *search_value;
1924
1925 // Elements beyond the capacity of the backing store treated as undefined.
1926 if (value == undefined &&
1927 static_cast<uint32_t>(elements_base->length()) < length) {
1928 return Just(true);
1929 }
1930
1931 if (start_from >= length) return Just(false);
1932
1933 length = std::min(static_cast<uint32_t>(elements_base->length()), length);
1934
1935 if (!value->IsNumber()) {
1936 if (value == undefined) {
1937 // Only FAST_ELEMENTS, FAST_HOLEY_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, and
1938 // FAST_HOLEY_DOUBLE_ELEMENTS can have `undefined` as a value.
1939 if (!IsFastObjectElementsKind(Subclass::kind()) &&
1940 !IsFastHoleyElementsKind(Subclass::kind())) {
1941 return Just(false);
1942 }
1943
1944 // Search for `undefined` or The Hole in FAST_ELEMENTS,
1945 // FAST_HOLEY_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS
1946 if (IsFastSmiOrObjectElementsKind(Subclass::kind())) {
1947 auto elements = FixedArray::cast(receiver->elements());
1948
1949 for (uint32_t k = start_from; k < length; ++k) {
1950 Object* element_k = elements->get(k);
1951
1952 if (IsFastHoleyElementsKind(Subclass::kind()) &&
1953 element_k == the_hole) {
1954 return Just(true);
1955 }
1956 if (IsFastObjectElementsKind(Subclass::kind()) &&
1957 element_k == undefined) {
1958 return Just(true);
1959 }
1960 }
1961 return Just(false);
1962 } else {
1963 // Seach for The Hole in FAST_HOLEY_DOUBLE_ELEMENTS
1964 DCHECK_EQ(Subclass::kind(), FAST_HOLEY_DOUBLE_ELEMENTS);
1965 auto elements = FixedDoubleArray::cast(receiver->elements());
1966
1967 for (uint32_t k = start_from; k < length; ++k) {
1968 if (IsFastHoleyElementsKind(Subclass::kind()) &&
1969 elements->is_the_hole(k)) {
1970 return Just(true);
1971 }
1972 }
1973 return Just(false);
1974 }
1975 } else if (!IsFastObjectElementsKind(Subclass::kind())) {
1976 // Search for non-number, non-Undefined value, with either
1977 // FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS or
1978 // FAST_HOLEY_DOUBLE_ELEMENTS. Guaranteed to return false, since these
1979 // elements kinds can only contain Number values or undefined.
1980 return Just(false);
1981 } else {
1982 // Search for non-number, non-Undefined value with either
1983 // FAST_ELEMENTS or FAST_HOLEY_ELEMENTS.
1984 DCHECK(IsFastObjectElementsKind(Subclass::kind()));
1985 auto elements = FixedArray::cast(receiver->elements());
1986
1987 for (uint32_t k = start_from; k < length; ++k) {
1988 Object* element_k = elements->get(k);
1989 if (IsFastHoleyElementsKind(Subclass::kind()) &&
1990 element_k == the_hole) {
1991 continue;
1992 }
1993
1994 if (value->SameValueZero(element_k)) return Just(true);
1995 }
1996 return Just(false);
1997 }
1998 } else {
1999 if (!value->IsNaN()) {
2000 double search_value = value->Number();
2001 if (IsFastDoubleElementsKind(Subclass::kind())) {
2002 // Search for non-NaN Number in FAST_DOUBLE_ELEMENTS or
2003 // FAST_HOLEY_DOUBLE_ELEMENTS --- Skip TheHole, and trust UCOMISD or
2004 // similar operation for result.
2005 auto elements = FixedDoubleArray::cast(receiver->elements());
2006
2007 for (uint32_t k = start_from; k < length; ++k) {
2008 if (IsFastHoleyElementsKind(Subclass::kind()) &&
2009 elements->is_the_hole(k)) {
2010 continue;
2011 }
2012 if (elements->get_scalar(k) == search_value) return Just(true);
2013 }
2014 return Just(false);
2015 } else {
2016 // Search for non-NaN Number in FAST_ELEMENTS, FAST_HOLEY_ELEMENTS,
2017 // FAST_SMI_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS --- Skip non-Numbers,
2018 // and trust UCOMISD or similar operation for result
2019 auto elements = FixedArray::cast(receiver->elements());
2020
2021 for (uint32_t k = start_from; k < length; ++k) {
2022 Object* element_k = elements->get(k);
2023 if (element_k->IsNumber() && element_k->Number() == search_value) {
2024 return Just(true);
2025 }
2026 }
2027 return Just(false);
2028 }
2029 } else {
2030 // Search for NaN --- NaN cannot be represented with Smi elements, so
2031 // abort if ElementsKind is FAST_SMI_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS
2032 if (IsFastSmiElementsKind(Subclass::kind())) return Just(false);
2033
2034 if (IsFastDoubleElementsKind(Subclass::kind())) {
2035 // Search for NaN in FAST_DOUBLE_ELEMENTS or
2036 // FAST_HOLEY_DOUBLE_ELEMENTS --- Skip The Hole and trust
2037 // std::isnan(elementK) for result
2038 auto elements = FixedDoubleArray::cast(receiver->elements());
2039
2040 for (uint32_t k = start_from; k < length; ++k) {
2041 if (IsFastHoleyElementsKind(Subclass::kind()) &&
2042 elements->is_the_hole(k)) {
2043 continue;
2044 }
2045 if (std::isnan(elements->get_scalar(k))) return Just(true);
2046 }
2047 return Just(false);
2048 } else {
2049 // Search for NaN in FAST_ELEMENTS, FAST_HOLEY_ELEMENTS,
2050 // FAST_SMI_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS. Return true if
2051 // elementK->IsHeapNumber() && std::isnan(elementK->Number())
2052 DCHECK(IsFastSmiOrObjectElementsKind(Subclass::kind()));
2053 auto elements = FixedArray::cast(receiver->elements());
2054
2055 for (uint32_t k = start_from; k < length; ++k) {
2056 if (elements->get(k)->IsNaN()) return Just(true);
2057 }
2058 return Just(false);
2059 }
2060 }
2061 }
2062 }
2063
2064 private: 1783 private:
2065 // SpliceShrinkStep might modify the backing_store. 1784 // SpliceShrinkStep might modify the backing_store.
2066 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, 1785 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver,
2067 Handle<FixedArrayBase> backing_store, 1786 Handle<FixedArrayBase> backing_store,
2068 uint32_t start, uint32_t delete_count, 1787 uint32_t start, uint32_t delete_count,
2069 uint32_t add_count, uint32_t len, 1788 uint32_t add_count, uint32_t len,
2070 uint32_t new_length) { 1789 uint32_t new_length) {
2071 const int move_left_count = len - delete_count - start; 1790 const int move_left_count = len - delete_count - start;
2072 const int move_left_dst_index = start + add_count; 1791 const int move_left_dst_index = start + add_count;
2073 Subclass::MoveElements(isolate, receiver, backing_store, 1792 Subclass::MoveElements(isolate, receiver, backing_store,
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
2399 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> > { 2118 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> > {
2400 public: 2119 public:
2401 explicit FastHoleyDoubleElementsAccessor(const char* name) 2120 explicit FastHoleyDoubleElementsAccessor(const char* name)
2402 : FastDoubleElementsAccessor< 2121 : FastDoubleElementsAccessor<
2403 FastHoleyDoubleElementsAccessor, 2122 FastHoleyDoubleElementsAccessor,
2404 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> >(name) {} 2123 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> >(name) {}
2405 }; 2124 };
2406 2125
2407 2126
2408 // Super class for all external element arrays. 2127 // Super class for all external element arrays.
2409 template <ElementsKind Kind, typename ctype> 2128 template<ElementsKind Kind>
2410 class TypedElementsAccessor 2129 class TypedElementsAccessor
2411 : public ElementsAccessorBase<TypedElementsAccessor<Kind, ctype>, 2130 : public ElementsAccessorBase<TypedElementsAccessor<Kind>,
2412 ElementsKindTraits<Kind>> { 2131 ElementsKindTraits<Kind> > {
2413 public: 2132 public:
2414 explicit TypedElementsAccessor(const char* name) 2133 explicit TypedElementsAccessor(const char* name)
2415 : ElementsAccessorBase<AccessorClass, 2134 : ElementsAccessorBase<AccessorClass,
2416 ElementsKindTraits<Kind> >(name) {} 2135 ElementsKindTraits<Kind> >(name) {}
2417 2136
2418 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 2137 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
2419 typedef TypedElementsAccessor<Kind, ctype> AccessorClass; 2138 typedef TypedElementsAccessor<Kind> AccessorClass;
2420 2139
2421 static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, 2140 static inline void SetImpl(Handle<JSObject> holder, uint32_t entry,
2422 Object* value) { 2141 Object* value) {
2423 SetImpl(holder->elements(), entry, value); 2142 SetImpl(holder->elements(), entry, value);
2424 } 2143 }
2425 2144
2426 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 2145 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
2427 Object* value) { 2146 Object* value) {
2428 BackingStore::cast(backing_store)->SetValue(entry, value); 2147 BackingStore::cast(backing_store)->SetValue(entry, value);
2429 } 2148 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2515 Handle<Object> value = AccessorClass::GetImpl(*elements, index); 2234 Handle<Object> value = AccessorClass::GetImpl(*elements, index);
2516 if (get_entries) { 2235 if (get_entries) {
2517 value = MakeEntryPair(isolate, index, value); 2236 value = MakeEntryPair(isolate, index, value);
2518 } 2237 }
2519 values_or_entries->set(count++, *value); 2238 values_or_entries->set(count++, *value);
2520 } 2239 }
2521 } 2240 }
2522 *nof_items = count; 2241 *nof_items = count;
2523 return Just(true); 2242 return Just(true);
2524 } 2243 }
2525
2526 static Maybe<bool> IncludesValueImpl(Isolate* isolate,
2527 Handle<JSObject> receiver,
2528 Handle<Object> value,
2529 uint32_t start_from, uint32_t length) {
2530 DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver));
2531 DisallowHeapAllocation no_gc;
2532
2533 BackingStore* elements = BackingStore::cast(receiver->elements());
2534 if (value->IsUndefined(isolate) &&
2535 length > static_cast<uint32_t>(elements->length())) {
2536 return Just(true);
2537 }
2538 if (!value->IsNumber()) return Just(false);
2539
2540 double search_value = value->Number();
2541
2542 if (!std::isfinite(search_value)) {
2543 // Integral types cannot represent +Inf or NaN
2544 if (AccessorClass::kind() < FLOAT32_ELEMENTS ||
2545 AccessorClass::kind() > FLOAT64_ELEMENTS) {
2546 return Just(false);
2547 }
2548 } else if (search_value < std::numeric_limits<ctype>::lowest() ||
2549 search_value > std::numeric_limits<ctype>::max()) {
2550 // Return false if value can't be represented in this space
2551 return Just(false);
2552 }
2553
2554 if (!std::isnan(search_value)) {
2555 for (uint32_t k = start_from; k < length; ++k) {
2556 double element_k = elements->get_scalar(k);
2557 if (element_k == search_value) return Just(true);
2558 }
2559 return Just(false);
2560 } else {
2561 for (uint32_t k = start_from; k < length; ++k) {
2562 double element_k = elements->get_scalar(k);
2563 if (std::isnan(element_k)) return Just(true);
2564 }
2565 return Just(false);
2566 }
2567 }
2568 }; 2244 };
2569 2245
2570 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ 2246
2571 typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \ 2247
2248 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \
2249 typedef TypedElementsAccessor<TYPE##_ELEMENTS > \
2572 Fixed##Type##ElementsAccessor; 2250 Fixed##Type##ElementsAccessor;
2573 2251
2574 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) 2252 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR)
2575 #undef FIXED_ELEMENTS_ACCESSOR 2253 #undef FIXED_ELEMENTS_ACCESSOR
2576 2254
2577 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits> 2255 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits>
2578 class SloppyArgumentsElementsAccessor 2256 class SloppyArgumentsElementsAccessor
2579 : public ElementsAccessorBase<Subclass, KindTraits> { 2257 : public ElementsAccessorBase<Subclass, KindTraits> {
2580 public: 2258 public:
2581 explicit SloppyArgumentsElementsAccessor(const char* name) 2259 explicit SloppyArgumentsElementsAccessor(const char* name)
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
2796 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); 2474 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER);
2797 } 2475 }
2798 insertion_index++; 2476 insertion_index++;
2799 } 2477 }
2800 2478
2801 Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1))); 2479 Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1)));
2802 return ArgumentsAccessor::DirectCollectElementIndicesImpl( 2480 return ArgumentsAccessor::DirectCollectElementIndicesImpl(
2803 isolate, object, store, convert, filter, list, nof_indices, 2481 isolate, object, store, convert, filter, list, nof_indices,
2804 insertion_index); 2482 insertion_index);
2805 } 2483 }
2806
2807 static Maybe<bool> IncludesValueImpl(Isolate* isolate,
2808 Handle<JSObject> object,
2809 Handle<Object> value,
2810 uint32_t start_from, uint32_t length) {
2811 DCHECK(JSObject::PrototypeHasNoElements(isolate, *object));
2812 Handle<Map> original_map = handle(object->map(), isolate);
2813 FixedArray* parameter_map = FixedArray::cast(object->elements());
2814 bool search_for_hole = value->IsUndefined(isolate);
2815
2816 for (uint32_t k = start_from; k < length; ++k) {
2817 uint32_t entry =
2818 GetEntryForIndexImpl(*object, parameter_map, k, ALL_PROPERTIES);
2819 if (entry == kMaxUInt32) {
2820 if (search_for_hole) return Just(true);
2821 continue;
2822 }
2823
2824 Handle<Object> element_k = GetImpl(parameter_map, entry);
2825
2826 if (element_k->IsAccessorPair()) {
2827 LookupIterator it(isolate, object, k, LookupIterator::OWN);
2828 DCHECK(it.IsFound());
2829 DCHECK_EQ(it.state(), LookupIterator::ACCESSOR);
2830 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k,
2831 Object::GetPropertyWithAccessor(&it),
2832 Nothing<bool>());
2833
2834 if (value->SameValueZero(*element_k)) return Just(true);
2835
2836 if (object->map() != *original_map) {
2837 // Some mutation occurred in accessor. Abort "fast" path
2838 return IncludesValueSlowPath(isolate, object, value, k + 1, length);
2839 }
2840 } else if (value->SameValueZero(*element_k)) {
2841 return Just(true);
2842 }
2843 }
2844 return Just(false);
2845 }
2846 }; 2484 };
2847 2485
2848 2486
2849 class SlowSloppyArgumentsElementsAccessor 2487 class SlowSloppyArgumentsElementsAccessor
2850 : public SloppyArgumentsElementsAccessor< 2488 : public SloppyArgumentsElementsAccessor<
2851 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, 2489 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
2852 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > { 2490 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > {
2853 public: 2491 public:
2854 explicit SlowSloppyArgumentsElementsAccessor(const char* name) 2492 explicit SlowSloppyArgumentsElementsAccessor(const char* name)
2855 : SloppyArgumentsElementsAccessor< 2493 : SloppyArgumentsElementsAccessor<
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
3443 insertion_index += len; 3081 insertion_index += len;
3444 } 3082 }
3445 3083
3446 DCHECK_EQ(insertion_index, result_len); 3084 DCHECK_EQ(insertion_index, result_len);
3447 return result_array; 3085 return result_array;
3448 } 3086 }
3449 3087
3450 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 3088 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
3451 } // namespace internal 3089 } // namespace internal
3452 } // namespace v8 3090 } // namespace v8
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698