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

Side by Side Diff: src/elements.cc

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

Powered by Google App Engine
This is Rietveld 408576698