Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index 20e358848a7938c1a13eb7d2126777847dd309e3..7db641649f5ba204b17806f94144fb9e6dc59eaf 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -468,27 +468,6 @@ |
} |
} |
-static Maybe<bool> IncludesValueSlowPath(Isolate* isolate, |
- Handle<JSObject> receiver, |
- Handle<Object> value, |
- uint32_t start_from, uint32_t length) { |
- bool search_for_hole = value->IsUndefined(isolate); |
- for (uint32_t k = start_from; k < length; ++k) { |
- LookupIterator it(isolate, receiver, k); |
- if (!it.IsFound()) { |
- if (search_for_hole) return Just(true); |
- continue; |
- } |
- Handle<Object> element_k; |
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k, |
- Object::GetProperty(&it), Nothing<bool>()); |
- |
- if (value->SameValueZero(*element_k)) return Just(true); |
- } |
- |
- return Just(false); |
-} |
- |
// Base class for element handler implementations. Contains the |
// the common logic for objects with different ElementsKinds. |
// Subclasses must specialize method for which the element |
@@ -1103,20 +1082,6 @@ |
uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { |
return Subclass::GetCapacityImpl(holder, backing_store); |
- } |
- |
- static Maybe<bool> IncludesValueImpl(Isolate* isolate, |
- Handle<JSObject> receiver, |
- Handle<Object> value, |
- uint32_t start_from, uint32_t length) { |
- return IncludesValueSlowPath(isolate, receiver, value, start_from, length); |
- } |
- |
- Maybe<bool> IncludesValue(Isolate* isolate, Handle<JSObject> receiver, |
- Handle<Object> value, uint32_t start_from, |
- uint32_t length) final { |
- return Subclass::IncludesValueImpl(isolate, receiver, value, start_from, |
- length); |
} |
static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
@@ -1455,102 +1420,6 @@ |
accumulator->AddKey(value, convert); |
} |
} |
- |
- static bool IncludesValueFastPath(Isolate* isolate, Handle<JSObject> receiver, |
- Handle<Object> value, uint32_t start_from, |
- uint32_t length, Maybe<bool>* result) { |
- DisallowHeapAllocation no_gc; |
- SeededNumberDictionary* dictionary = |
- SeededNumberDictionary::cast(receiver->elements()); |
- int capacity = dictionary->Capacity(); |
- Object* the_hole = isolate->heap()->the_hole_value(); |
- Object* undefined = isolate->heap()->undefined_value(); |
- |
- // Scan for accessor properties. If accessors are present, then elements |
- // must be accessed in order via the slow path. |
- bool found = false; |
- for (int i = 0; i < capacity; ++i) { |
- Object* k = dictionary->KeyAt(i); |
- if (k == the_hole) continue; |
- if (k == undefined) continue; |
- |
- uint32_t index; |
- if (!k->ToArrayIndex(&index) || index < start_from || index >= length) { |
- continue; |
- } |
- |
- if (dictionary->DetailsAt(i).type() == ACCESSOR_CONSTANT) { |
- // Restart from beginning in slow path, otherwise we may observably |
- // access getters out of order |
- return false; |
- } else if (!found) { |
- Object* element_k = dictionary->ValueAt(i); |
- if (value->SameValueZero(element_k)) found = true; |
- } |
- } |
- |
- *result = Just(found); |
- return true; |
- } |
- |
- static Maybe<bool> IncludesValueImpl(Isolate* isolate, |
- Handle<JSObject> receiver, |
- Handle<Object> value, |
- uint32_t start_from, uint32_t length) { |
- DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); |
- bool search_for_hole = value->IsUndefined(isolate); |
- |
- if (!search_for_hole) { |
- Maybe<bool> result = Nothing<bool>(); |
- if (DictionaryElementsAccessor::IncludesValueFastPath( |
- isolate, receiver, value, start_from, length, &result)) { |
- return result; |
- } |
- } |
- |
- Handle<SeededNumberDictionary> dictionary( |
- SeededNumberDictionary::cast(receiver->elements()), isolate); |
- // Iterate through entire range, as accessing elements out of order is |
- // observable |
- for (uint32_t k = start_from; k < length; ++k) { |
- int entry = dictionary->FindEntry(k); |
- if (entry == SeededNumberDictionary::kNotFound) { |
- if (search_for_hole) return Just(true); |
- continue; |
- } |
- |
- PropertyDetails details = GetDetailsImpl(receiver->elements(), entry); |
- switch (details.kind()) { |
- case kData: { |
- Object* element_k = dictionary->ValueAt(entry); |
- if (value->SameValueZero(element_k)) return Just(true); |
- break; |
- } |
- case kAccessor: { |
- LookupIterator it(isolate, receiver, k, |
- LookupIterator::OWN_SKIP_INTERCEPTOR); |
- DCHECK(it.IsFound()); |
- DCHECK_EQ(it.state(), LookupIterator::ACCESSOR); |
- Handle<Object> element_k; |
- |
- ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
- isolate, element_k, JSObject::GetPropertyWithAccessor(&it), |
- Nothing<bool>()); |
- |
- if (value->SameValueZero(*element_k)) return Just(true); |
- |
- // Some mutation to the prototype elements may have occurred in |
- // accessor. |
- if (!JSObject::PrototypeHasNoElements(isolate, *receiver)) { |
- return IncludesValueSlowPath(isolate, receiver, value, k + 1, |
- length); |
- } |
- break; |
- } |
- } |
- } |
- return Just(false); |
- } |
}; |
@@ -1908,156 +1777,6 @@ |
} |
if (hole_start != hole_end) { |
dst_elms->FillWithHoles(hole_start, hole_end); |
- } |
- } |
- |
- static Maybe<bool> IncludesValueImpl(Isolate* isolate, |
- Handle<JSObject> receiver, |
- Handle<Object> search_value, |
- uint32_t start_from, uint32_t length) { |
- DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); |
- DisallowHeapAllocation no_gc; |
- FixedArrayBase* elements_base = receiver->elements(); |
- Object* the_hole = isolate->heap()->the_hole_value(); |
- Object* undefined = isolate->heap()->undefined_value(); |
- Object* value = *search_value; |
- |
- // Elements beyond the capacity of the backing store treated as undefined. |
- if (value == undefined && |
- static_cast<uint32_t>(elements_base->length()) < length) { |
- return Just(true); |
- } |
- |
- if (start_from >= length) return Just(false); |
- |
- length = std::min(static_cast<uint32_t>(elements_base->length()), length); |
- |
- if (!value->IsNumber()) { |
- if (value == undefined) { |
- // Only FAST_ELEMENTS, FAST_HOLEY_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, and |
- // FAST_HOLEY_DOUBLE_ELEMENTS can have `undefined` as a value. |
- if (!IsFastObjectElementsKind(Subclass::kind()) && |
- !IsFastHoleyElementsKind(Subclass::kind())) { |
- return Just(false); |
- } |
- |
- // Search for `undefined` or The Hole in FAST_ELEMENTS, |
- // FAST_HOLEY_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS |
- if (IsFastSmiOrObjectElementsKind(Subclass::kind())) { |
- auto elements = FixedArray::cast(receiver->elements()); |
- |
- for (uint32_t k = start_from; k < length; ++k) { |
- Object* element_k = elements->get(k); |
- |
- if (IsFastHoleyElementsKind(Subclass::kind()) && |
- element_k == the_hole) { |
- return Just(true); |
- } |
- if (IsFastObjectElementsKind(Subclass::kind()) && |
- element_k == undefined) { |
- return Just(true); |
- } |
- } |
- return Just(false); |
- } else { |
- // Seach for The Hole in FAST_HOLEY_DOUBLE_ELEMENTS |
- DCHECK_EQ(Subclass::kind(), FAST_HOLEY_DOUBLE_ELEMENTS); |
- auto elements = FixedDoubleArray::cast(receiver->elements()); |
- |
- for (uint32_t k = start_from; k < length; ++k) { |
- if (IsFastHoleyElementsKind(Subclass::kind()) && |
- elements->is_the_hole(k)) { |
- return Just(true); |
- } |
- } |
- return Just(false); |
- } |
- } else if (!IsFastObjectElementsKind(Subclass::kind())) { |
- // Search for non-number, non-Undefined value, with either |
- // FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS or |
- // FAST_HOLEY_DOUBLE_ELEMENTS. Guaranteed to return false, since these |
- // elements kinds can only contain Number values or undefined. |
- return Just(false); |
- } else { |
- // Search for non-number, non-Undefined value with either |
- // FAST_ELEMENTS or FAST_HOLEY_ELEMENTS. |
- DCHECK(IsFastObjectElementsKind(Subclass::kind())); |
- auto elements = FixedArray::cast(receiver->elements()); |
- |
- for (uint32_t k = start_from; k < length; ++k) { |
- Object* element_k = elements->get(k); |
- if (IsFastHoleyElementsKind(Subclass::kind()) && |
- element_k == the_hole) { |
- continue; |
- } |
- |
- if (value->SameValueZero(element_k)) return Just(true); |
- } |
- return Just(false); |
- } |
- } else { |
- if (!value->IsNaN()) { |
- double search_value = value->Number(); |
- if (IsFastDoubleElementsKind(Subclass::kind())) { |
- // Search for non-NaN Number in FAST_DOUBLE_ELEMENTS or |
- // FAST_HOLEY_DOUBLE_ELEMENTS --- Skip TheHole, and trust UCOMISD or |
- // similar operation for result. |
- auto elements = FixedDoubleArray::cast(receiver->elements()); |
- |
- for (uint32_t k = start_from; k < length; ++k) { |
- if (IsFastHoleyElementsKind(Subclass::kind()) && |
- elements->is_the_hole(k)) { |
- continue; |
- } |
- if (elements->get_scalar(k) == search_value) return Just(true); |
- } |
- return Just(false); |
- } else { |
- // Search for non-NaN Number in FAST_ELEMENTS, FAST_HOLEY_ELEMENTS, |
- // FAST_SMI_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS --- Skip non-Numbers, |
- // and trust UCOMISD or similar operation for result |
- auto elements = FixedArray::cast(receiver->elements()); |
- |
- for (uint32_t k = start_from; k < length; ++k) { |
- Object* element_k = elements->get(k); |
- if (element_k->IsNumber() && element_k->Number() == search_value) { |
- return Just(true); |
- } |
- } |
- return Just(false); |
- } |
- } else { |
- // Search for NaN --- NaN cannot be represented with Smi elements, so |
- // abort if ElementsKind is FAST_SMI_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS |
- if (IsFastSmiElementsKind(Subclass::kind())) return Just(false); |
- |
- if (IsFastDoubleElementsKind(Subclass::kind())) { |
- // Search for NaN in FAST_DOUBLE_ELEMENTS or |
- // FAST_HOLEY_DOUBLE_ELEMENTS --- Skip The Hole and trust |
- // std::isnan(elementK) for result |
- auto elements = FixedDoubleArray::cast(receiver->elements()); |
- |
- for (uint32_t k = start_from; k < length; ++k) { |
- if (IsFastHoleyElementsKind(Subclass::kind()) && |
- elements->is_the_hole(k)) { |
- continue; |
- } |
- if (std::isnan(elements->get_scalar(k))) return Just(true); |
- } |
- return Just(false); |
- } else { |
- // Search for NaN in FAST_ELEMENTS, FAST_HOLEY_ELEMENTS, |
- // FAST_SMI_ELEMENTS or FAST_HOLEY_SMI_ELEMENTS. Return true if |
- // elementK->IsHeapNumber() && std::isnan(elementK->Number()) |
- DCHECK(IsFastSmiOrObjectElementsKind(Subclass::kind())); |
- auto elements = FixedArray::cast(receiver->elements()); |
- |
- for (uint32_t k = start_from; k < length; ++k) { |
- if (elements->get(k)->IsNaN()) return Just(true); |
- } |
- return Just(false); |
- } |
- } |
} |
} |
@@ -2406,17 +2125,17 @@ |
// Super class for all external element arrays. |
-template <ElementsKind Kind, typename ctype> |
+template<ElementsKind Kind> |
class TypedElementsAccessor |
- : public ElementsAccessorBase<TypedElementsAccessor<Kind, ctype>, |
- ElementsKindTraits<Kind>> { |
+ : public ElementsAccessorBase<TypedElementsAccessor<Kind>, |
+ ElementsKindTraits<Kind> > { |
public: |
explicit TypedElementsAccessor(const char* name) |
: ElementsAccessorBase<AccessorClass, |
ElementsKindTraits<Kind> >(name) {} |
typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; |
- typedef TypedElementsAccessor<Kind, ctype> AccessorClass; |
+ typedef TypedElementsAccessor<Kind> AccessorClass; |
static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, |
Object* value) { |
@@ -2522,53 +2241,12 @@ |
*nof_items = count; |
return Just(true); |
} |
- |
- static Maybe<bool> IncludesValueImpl(Isolate* isolate, |
- Handle<JSObject> receiver, |
- Handle<Object> value, |
- uint32_t start_from, uint32_t length) { |
- DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver)); |
- DisallowHeapAllocation no_gc; |
- |
- BackingStore* elements = BackingStore::cast(receiver->elements()); |
- if (value->IsUndefined(isolate) && |
- length > static_cast<uint32_t>(elements->length())) { |
- return Just(true); |
- } |
- if (!value->IsNumber()) return Just(false); |
- |
- double search_value = value->Number(); |
- |
- if (!std::isfinite(search_value)) { |
- // Integral types cannot represent +Inf or NaN |
- if (AccessorClass::kind() < FLOAT32_ELEMENTS || |
- AccessorClass::kind() > FLOAT64_ELEMENTS) { |
- return Just(false); |
- } |
- } else if (search_value < std::numeric_limits<ctype>::lowest() || |
- search_value > std::numeric_limits<ctype>::max()) { |
- // Return false if value can't be represented in this space |
- return Just(false); |
- } |
- |
- if (!std::isnan(search_value)) { |
- for (uint32_t k = start_from; k < length; ++k) { |
- double element_k = elements->get_scalar(k); |
- if (element_k == search_value) return Just(true); |
- } |
- return Just(false); |
- } else { |
- for (uint32_t k = start_from; k < length; ++k) { |
- double element_k = elements->get_scalar(k); |
- if (std::isnan(element_k)) return Just(true); |
- } |
- return Just(false); |
- } |
- } |
}; |
-#define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
- typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \ |
+ |
+ |
+#define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
+ typedef TypedElementsAccessor<TYPE##_ELEMENTS > \ |
Fixed##Type##ElementsAccessor; |
TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) |
@@ -2803,46 +2481,6 @@ |
isolate, object, store, convert, filter, list, nof_indices, |
insertion_index); |
} |
- |
- static Maybe<bool> IncludesValueImpl(Isolate* isolate, |
- Handle<JSObject> object, |
- Handle<Object> value, |
- uint32_t start_from, uint32_t length) { |
- DCHECK(JSObject::PrototypeHasNoElements(isolate, *object)); |
- Handle<Map> original_map = handle(object->map(), isolate); |
- FixedArray* parameter_map = FixedArray::cast(object->elements()); |
- bool search_for_hole = value->IsUndefined(isolate); |
- |
- for (uint32_t k = start_from; k < length; ++k) { |
- uint32_t entry = |
- GetEntryForIndexImpl(*object, parameter_map, k, ALL_PROPERTIES); |
- if (entry == kMaxUInt32) { |
- if (search_for_hole) return Just(true); |
- continue; |
- } |
- |
- Handle<Object> element_k = GetImpl(parameter_map, entry); |
- |
- if (element_k->IsAccessorPair()) { |
- LookupIterator it(isolate, object, k, LookupIterator::OWN); |
- DCHECK(it.IsFound()); |
- DCHECK_EQ(it.state(), LookupIterator::ACCESSOR); |
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, element_k, |
- Object::GetPropertyWithAccessor(&it), |
- Nothing<bool>()); |
- |
- if (value->SameValueZero(*element_k)) return Just(true); |
- |
- if (object->map() != *original_map) { |
- // Some mutation occurred in accessor. Abort "fast" path |
- return IncludesValueSlowPath(isolate, object, value, k + 1, length); |
- } |
- } else if (value->SameValueZero(*element_k)) { |
- return Just(true); |
- } |
- } |
- return Just(false); |
- } |
}; |