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

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: fix some things, rebase, rename some variables in TF, etc 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
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) {
Camillo Bruni 2016/07/28 12:57:29 nit: expose this globally and use the common imple
caitp 2016/07/29 20:27:47 The builtin has to deal with non-JSObject receiver
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 Maybe<bool> IncludesValueImpl(Isolate* isolate,
1460 Handle<JSObject> receiver,
1461 Handle<Object> value,
1462 uint32_t start_from, uint32_t length) {
1463 Handle<SeededNumberDictionary> dictionary(
1464 SeededNumberDictionary::cast(receiver->elements()), isolate);
1465
1466 bool search_for_hole = value->IsUndefined(isolate);
1467 if (search_for_hole) goto slow_path;
Camillo Bruni 2016/07/28 12:57:29 shush, I didn't see this goto :D. For the sake of
caitp 2016/07/29 20:27:46 Done.
1468 goto slow_path;
1469 {
1470 DisallowHeapAllocation no_gc;
1471 int capacity = dictionary->Capacity();
1472 Object* the_hole = isolate->heap()->the_hole_value();
1473 for (int i = 0; i < capacity; ++i) {
1474 Object* k = dictionary->KeyAt(i);
1475 if (!dictionary->IsKey(k)) continue;
1476
1477 Object* element_k = dictionary->ValueAt(i);
1478 if (element_k == the_hole) continue;
1479
1480 switch (dictionary->DetailsAt(i).kind()) {
1481 case kData: {
1482 if (value->SameValueZero(element_k)) return Just(true);
1483 break;
1484 }
1485 case kAccessor: {
1486 // Restart from beginning in slow path, otherwise we may observably
1487 // access getters out of order
1488 goto slow_path;
1489 }
1490 }
1491 }
1492 return Just(false);
1493 }
1494
1495 slow_path:
1496 // Iterate through entire range, as accessing elements out of order is
1497 // observable
1498 for (uint32_t k = start_from; k < length; ++k) {
1499 int entry = dictionary->FindEntry(k);
1500 if (entry == SeededNumberDictionary::kNotFound) {
1501 if (search_for_hole) return Just(true);
1502 continue;
1503 }
1504
1505 PropertyDetails details = GetDetailsImpl(receiver->elements(), entry);
1506 switch (details.kind()) {
1507 case kData: {
1508 Object* element_k = dictionary->ValueAt(entry);
1509 if (value->SameValueZero(element_k)) return Just(true);
1510 break;
1511 }
1512 case kAccessor: {
1513 LookupIterator it(isolate, receiver, k, LookupIterator::OWN);
Camillo Bruni 2016/07/28 12:57:29 nit: You can minimally speed up the lookup iterato
caitp 2016/07/29 20:27:47 Done.
1514 DCHECK(it.IsFound());
1515 DCHECK_EQ(it.state(), LookupIterator::ACCESSOR);
1516 Handle<Object> element_k;
1517
1518 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
1519 isolate, element_k, JSObject::GetPropertyWithAccessor(&it),
1520 Nothing<bool>());
1521
1522 if (value->SameValueZero(*element_k)) return Just(true);
1523
1524 // Some mutation to the prototype elements may have occurred in
1525 // accessor.
1526 if (!JSObject::PrototypeHasNoElements(isolate, *receiver)) {
1527 return IncludesValueSlowPath(isolate, receiver, value, k + 1,
1528 length);
1529 }
1530 break;
1531 }
1532 }
1533 }
1534 return Just(false);
1535 }
1423 }; 1536 };
1424 1537
1425 1538
1426 // Super class for all fast element arrays. 1539 // Super class for all fast element arrays.
1427 template <typename Subclass, typename KindTraits> 1540 template <typename Subclass, typename KindTraits>
1428 class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { 1541 class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
1429 public: 1542 public:
1430 explicit FastElementsAccessor(const char* name) 1543 explicit FastElementsAccessor(const char* name)
1431 : ElementsAccessorBase<Subclass, KindTraits>(name) {} 1544 : ElementsAccessorBase<Subclass, KindTraits>(name) {}
1432 1545
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1773 DisallowHeapAllocation no_gc; 1886 DisallowHeapAllocation no_gc;
1774 heap->MoveElements(FixedArray::cast(*dst_elms), dst_index, src_index, 1887 heap->MoveElements(FixedArray::cast(*dst_elms), dst_index, src_index,
1775 len); 1888 len);
1776 } 1889 }
1777 } 1890 }
1778 if (hole_start != hole_end) { 1891 if (hole_start != hole_end) {
1779 dst_elms->FillWithHoles(hole_start, hole_end); 1892 dst_elms->FillWithHoles(hole_start, hole_end);
1780 } 1893 }
1781 } 1894 }
1782 1895
1896 static Maybe<bool> IncludesValueImpl(Isolate* isolate,
1897 Handle<JSObject> receiver,
1898 Handle<Object> search_value,
1899 uint32_t start_from, uint32_t length) {
1900 DisallowHeapAllocation no_gc;
1901 FixedArrayBase* elements_base = receiver->elements();
1902 Object* the_hole = isolate->heap()->the_hole_value();
1903 Object* undefined = isolate->heap()->undefined_value();
1904 Object* value = *search_value;
1905
1906 // Elements beyond the capacity of the backing store treated as undefined.
1907 if (value == undefined && elements_base->length() < length) {
1908 return Just(true);
1909 }
1910
1911 if (start_from >= length) return Just(false);
1912
1913 if (!value->IsNumber()) {
1914 if (value == undefined) {
1915 // Only FAST_ELEMENTS, FAST_HOLEY_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, and
1916 // FAST_HOLEY_DOUBLE_ELEMENTS can have `undefined` as a value.
1917 if (!IsFastObjectElementsKind(KindTraits::Kind) &&
1918 !IsFastHoleyElementsKind(KindTraits::Kind)) {
1919 return Just(false);
1920 }
1921 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) {
Camillo Bruni 2016/07/28 12:57:29 nit: please add comments to each branch on what yo
caitp 2016/07/29 20:27:47 Done.
1922 auto elements = FixedArray::cast(receiver->elements());
1923
1924 for (uint32_t k = start_from; k < length; ++k) {
1925 Object* element_k = elements->get(k);
1926
1927 if (IsFastHoleyElementsKind(KindTraits::Kind) &&
1928 element_k == the_hole) {
1929 return Just(true);
1930 }
1931 if (IsFastObjectElementsKind(KindTraits::Kind) &&
1932 element_k == undefined) {
1933 return Just(true);
1934 }
1935 }
1936 return Just(false);
1937 } else {
1938 // Loop searching for non-Number, non-Undefined elements
1939 auto elements = FixedDoubleArray::cast(receiver->elements());
1940
1941 for (uint32_t k = start_from; k < length; ++k) {
1942 if (IsFastHoleyElementsKind(KindTraits::Kind) &&
1943 elements->is_the_hole(k)) {
1944 return Just(true);
1945 }
1946 }
1947 return Just(false);
1948 }
1949 } else if (!IsFastObjectElementsKind(KindTraits::Kind)) {
1950 // Only Numbers can be represented as packed Smi or Double elements
1951 return Just(false);
1952 } else {
1953 auto elements = FixedArray::cast(receiver->elements());
1954
1955 for (uint32_t k = start_from; k < length; ++k) {
1956 Object* element_k = elements->get(k);
1957 if (IsFastHoleyElementsKind(KindTraits::Kind) &&
1958 element_k == the_hole) {
1959 continue;
1960 }
1961
1962 if (value->SameValueZero(element_k)) return Just(true);
1963 }
1964 return Just(false);
1965 }
1966 } else {
1967 if (!value->IsNaN()) {
1968 double search_value = value->Number();
1969 if (IsFastDoubleElementsKind(KindTraits::Kind)) {
1970 auto elements = FixedDoubleArray::cast(receiver->elements());
1971
1972 for (uint32_t k = start_from; k < length; ++k) {
1973 if (IsFastHoleyElementsKind(KindTraits::Kind) &&
1974 elements->is_the_hole(k)) {
1975 continue;
1976 }
1977 if (elements->get_scalar(k) == search_value) return Just(true);
1978 }
1979 return Just(false);
1980 } else {
1981 auto elements = FixedArray::cast(receiver->elements());
1982
1983 for (uint32_t k = start_from; k < length; ++k) {
1984 Object* element_k = elements->get(k);
1985 if (element_k->IsNumber() && element_k->Number() == search_value) {
1986 return Just(true);
1987 }
1988 }
1989 return Just(false);
1990 }
1991 } else {
1992 // NaN cannot be represented with Smi elements
1993 if (IsFastSmiElementsKind(KindTraits::Kind)) return Just(false);
1994
1995 if (IsFastDoubleElementsKind(KindTraits::Kind)) {
1996 auto elements = FixedDoubleArray::cast(receiver->elements());
1997
1998 for (uint32_t k = start_from; k < length; ++k) {
1999 if (IsFastHoleyElementsKind(KindTraits::Kind) &&
2000 elements->is_the_hole(k)) {
2001 continue;
2002 }
2003 if (std::isnan(elements->get_scalar(k))) return Just(true);
2004 }
2005 return Just(false);
2006 } else {
2007 auto elements = FixedArray::cast(receiver->elements());
2008
2009 for (uint32_t k = start_from; k < length; ++k) {
2010 if (elements->get(k)->IsNaN()) return Just(true);
2011 }
2012 return Just(false);
2013 }
2014 }
2015 }
2016 }
2017
1783 private: 2018 private:
1784 // SpliceShrinkStep might modify the backing_store. 2019 // SpliceShrinkStep might modify the backing_store.
1785 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, 2020 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver,
1786 Handle<FixedArrayBase> backing_store, 2021 Handle<FixedArrayBase> backing_store,
1787 uint32_t start, uint32_t delete_count, 2022 uint32_t start, uint32_t delete_count,
1788 uint32_t add_count, uint32_t len, 2023 uint32_t add_count, uint32_t len,
1789 uint32_t new_length) { 2024 uint32_t new_length) {
1790 const int move_left_count = len - delete_count - start; 2025 const int move_left_count = len - delete_count - start;
1791 const int move_left_dst_index = start + add_count; 2026 const int move_left_dst_index = start + add_count;
1792 Subclass::MoveElements(isolate, receiver, backing_store, 2027 Subclass::MoveElements(isolate, receiver, backing_store,
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
2118 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> > { 2353 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> > {
2119 public: 2354 public:
2120 explicit FastHoleyDoubleElementsAccessor(const char* name) 2355 explicit FastHoleyDoubleElementsAccessor(const char* name)
2121 : FastDoubleElementsAccessor< 2356 : FastDoubleElementsAccessor<
2122 FastHoleyDoubleElementsAccessor, 2357 FastHoleyDoubleElementsAccessor,
2123 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> >(name) {} 2358 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> >(name) {}
2124 }; 2359 };
2125 2360
2126 2361
2127 // Super class for all external element arrays. 2362 // Super class for all external element arrays.
2128 template<ElementsKind Kind> 2363 template <ElementsKind Kind, typename ctype>
Camillo Bruni 2016/07/28 12:57:29 nice :)
2129 class TypedElementsAccessor 2364 class TypedElementsAccessor
2130 : public ElementsAccessorBase<TypedElementsAccessor<Kind>, 2365 : public ElementsAccessorBase<TypedElementsAccessor<Kind, ctype>,
2131 ElementsKindTraits<Kind> > { 2366 ElementsKindTraits<Kind>> {
2132 public: 2367 public:
2133 explicit TypedElementsAccessor(const char* name) 2368 explicit TypedElementsAccessor(const char* name)
2134 : ElementsAccessorBase<AccessorClass, 2369 : ElementsAccessorBase<AccessorClass,
2135 ElementsKindTraits<Kind> >(name) {} 2370 ElementsKindTraits<Kind> >(name) {}
2136 2371
2137 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 2372 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
2138 typedef TypedElementsAccessor<Kind> AccessorClass; 2373 typedef TypedElementsAccessor<Kind, ctype> AccessorClass;
2139 2374
2140 static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, 2375 static inline void SetImpl(Handle<JSObject> holder, uint32_t entry,
2141 Object* value) { 2376 Object* value) {
2142 SetImpl(holder->elements(), entry, value); 2377 SetImpl(holder->elements(), entry, value);
2143 } 2378 }
2144 2379
2145 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 2380 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
2146 Object* value) { 2381 Object* value) {
2147 BackingStore::cast(backing_store)->SetValue(entry, value); 2382 BackingStore::cast(backing_store)->SetValue(entry, value);
2148 } 2383 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2234 Handle<Object> value = AccessorClass::GetImpl(*elements, index); 2469 Handle<Object> value = AccessorClass::GetImpl(*elements, index);
2235 if (get_entries) { 2470 if (get_entries) {
2236 value = MakeEntryPair(isolate, index, value); 2471 value = MakeEntryPair(isolate, index, value);
2237 } 2472 }
2238 values_or_entries->set(count++, *value); 2473 values_or_entries->set(count++, *value);
2239 } 2474 }
2240 } 2475 }
2241 *nof_items = count; 2476 *nof_items = count;
2242 return Just(true); 2477 return Just(true);
2243 } 2478 }
2479
2480 static Maybe<bool> IncludesValueImpl(Isolate* isolate,
2481 Handle<JSObject> receiver,
2482 Handle<Object> value,
2483 uint32_t start_from, uint32_t length) {
2484 DisallowHeapAllocation no_gc;
2485 auto HasNeuteredArrayBuffer = [](JSObject* object) -> bool {
Camillo Bruni 2016/07/28 12:57:29 can you just put this in a helper on this elements
caitp 2016/07/29 20:27:46 Done (moved to `static inline JSObject::HasNeutere
2486 switch (object->map()->instance_type()) {
2487 case JS_ARRAY_BUFFER_TYPE:
2488 return JSArrayBuffer::cast(object)->was_neutered();
2489 case JS_DATA_VIEW_TYPE:
2490 case JS_TYPED_ARRAY_TYPE: {
2491 Object* buffer = static_cast<JSArrayBufferView*>(object)->buffer();
2492 if (!buffer->IsJSArrayBuffer()) return false;
2493 return JSArrayBuffer::cast(buffer)->was_neutered();
2494 }
2495 default:
2496 return false;
2497 }
2498 };
2499
2500 // Don't exit early if buffers are neutred, because this is observable
2501 // via a thrown exception (but should still throw early).
2502 if (HasNeuteredArrayBuffer(*receiver)) {
2503 return IncludesValueSlowPath(isolate, receiver, value, start_from,
2504 length);
Camillo Bruni 2016/07/28 12:57:29 nit: If we have nothing on the prototype chain we
caitp 2016/07/29 20:27:46 Actually, I think this whole thing can be removed,
2505 }
2506
2507 BackingStore* elements = BackingStore::cast(receiver->elements());
2508 if (value->IsUndefined(isolate) && length > elements->length()) {
2509 return Just(true);
2510 }
2511 if (!value->IsNumber()) return Just(false);
2512
2513 double search_value = value->Number();
2514
2515 if (!std::isfinite(search_value)) {
2516 // Integral types cannot represent +Inf or NaN
2517 if (Kind < FLOAT32_ELEMENTS || Kind > FLOAT64_ELEMENTS) {
Camillo Bruni 2016/07/28 12:57:29 I think you can use kind() which is consistent acr
caitp 2016/07/29 20:27:47 Done
2518 return Just(false);
2519 }
2520 } else if (search_value < std::numeric_limits<ctype>::min() ||
caitp 2016/07/29 20:27:47 switched to numeric_limits<ctype>::lowest() rather
Camillo Bruni 2016/07/30 06:56:56 argh, good catch!
2521 search_value > std::numeric_limits<ctype>::max()) {
2522 // Return false if value can't be represented in this space
2523 return Just(false);
2524 }
2525
2526 if (!std::isnan(search_value)) {
2527 for (uint32_t k = start_from; k < length; ++k) {
2528 double element_k = elements->get_scalar(k);
2529 if (element_k == search_value) return Just(true);
2530 }
2531 return Just(false);
2532 } else {
2533 for (uint32_t k = start_from; k < length; ++k) {
2534 double element_k = elements->get_scalar(k);
2535 if (std::isnan(element_k)) return Just(true);
2536 }
2537 return Just(false);
2538 }
2539 }
2244 }; 2540 };
2245 2541
2246 2542 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \
2247 2543 typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \
2248 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \
2249 typedef TypedElementsAccessor<TYPE##_ELEMENTS > \
2250 Fixed##Type##ElementsAccessor; 2544 Fixed##Type##ElementsAccessor;
2251 2545
2252 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) 2546 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR)
2253 #undef FIXED_ELEMENTS_ACCESSOR 2547 #undef FIXED_ELEMENTS_ACCESSOR
2254 2548
2255 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits> 2549 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits>
2256 class SloppyArgumentsElementsAccessor 2550 class SloppyArgumentsElementsAccessor
2257 : public ElementsAccessorBase<Subclass, KindTraits> { 2551 : public ElementsAccessorBase<Subclass, KindTraits> {
2258 public: 2552 public:
2259 explicit SloppyArgumentsElementsAccessor(const char* name) 2553 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); 2768 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER);
2475 } 2769 }
2476 insertion_index++; 2770 insertion_index++;
2477 } 2771 }
2478 2772
2479 Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1))); 2773 Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1)));
2480 return ArgumentsAccessor::DirectCollectElementIndicesImpl( 2774 return ArgumentsAccessor::DirectCollectElementIndicesImpl(
2481 isolate, object, store, convert, filter, list, nof_indices, 2775 isolate, object, store, convert, filter, list, nof_indices,
2482 insertion_index); 2776 insertion_index);
2483 } 2777 }
2778
2779 static Maybe<bool> IncludesValueImpl(Isolate* isolate,
2780 Handle<JSObject> object,
2781 Handle<Object> value,
2782 uint32_t start_from, uint32_t length) {
2783 Handle<Map> original_map = handle(object->map(), isolate);
2784 FixedArray* parameter_map = FixedArray::cast(object->elements());
2785 bool search_for_hole = value->IsUndefined(isolate);
2786
2787 for (uint32_t k = start_from; k < length; ++k) {
2788 uint32_t entry =
2789 GetEntryForIndexImpl(*object, parameter_map, k, ALL_PROPERTIES);
2790 if (entry == kMaxUInt32) {
2791 if (search_for_hole) return Just(true);
2792 continue;
2793 }
2794
2795 Handle<Object> element_k = GetImpl(parameter_map, entry);
2796
2797 if (element_k->IsAccessorPair()) {
2798 LookupIterator it(isolate, object, k, LookupIterator::OWN);
2799 DCHECK(it.IsFound());
2800 DCHECK_EQ(it.state(), LookupIterator::ACCESSOR);
2801 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k,
2802 Object::GetPropertyWithAccessor(&it),
2803 Nothing<bool>());
2804
2805 if (value->SameValueZero(*element_k)) return Just(true);
2806
2807 if (object->map() != *original_map) {
2808 // Some mutation occurred in accessor. Abort "fast" path
2809 return IncludesValueSlowPath(isolate, object, value, k + 1, length);
2810 }
2811 } else if (value->SameValueZero(*element_k)) {
2812 return Just(true);
2813 }
2814 }
2815 return Just(false);
2816 }
2484 }; 2817 };
2485 2818
2486 2819
2487 class SlowSloppyArgumentsElementsAccessor 2820 class SlowSloppyArgumentsElementsAccessor
2488 : public SloppyArgumentsElementsAccessor< 2821 : public SloppyArgumentsElementsAccessor<
2489 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, 2822 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
2490 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > { 2823 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > {
2491 public: 2824 public:
2492 explicit SlowSloppyArgumentsElementsAccessor(const char* name) 2825 explicit SlowSloppyArgumentsElementsAccessor(const char* name)
2493 : SloppyArgumentsElementsAccessor< 2826 : SloppyArgumentsElementsAccessor<
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
3081 insertion_index += len; 3414 insertion_index += len;
3082 } 3415 }
3083 3416
3084 DCHECK_EQ(insertion_index, result_len); 3417 DCHECK_EQ(insertion_index, result_len);
3085 return result_array; 3418 return result_array;
3086 } 3419 }
3087 3420
3088 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 3421 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
3089 } // namespace internal 3422 } // namespace internal
3090 } // namespace v8 3423 } // namespace v8
OLDNEW
« src/builtins/builtins.h ('K') | « src/elements.h ('k') | src/factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698