Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index 7436e15d688e9635d9277f8999781b7b13c9ede1..ccbdb40706262a611fa4d618ad14b1cccf611bdc 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -566,8 +566,10 @@ class ElementsAccessorBase : public ElementsAccessor { |
Handle<FixedArrayBase> backing_store, uint32_t start, |
uint32_t end) { |
if (IsFastPackedElementsKind(kind())) return true; |
+ Isolate* isolate = backing_store->GetIsolate(); |
for (uint32_t i = start; i < end; i++) { |
- if (!Subclass::HasElementImpl(holder, i, backing_store, ALL_PROPERTIES)) { |
+ if (!Subclass::HasElementImpl(isolate, holder, i, backing_store, |
+ ALL_PROPERTIES)) { |
return false; |
} |
} |
@@ -594,14 +596,16 @@ class ElementsAccessorBase : public ElementsAccessor { |
bool HasElement(Handle<JSObject> holder, uint32_t index, |
Handle<FixedArrayBase> backing_store, |
PropertyFilter filter) final { |
- return Subclass::HasElementImpl(holder, index, backing_store, filter); |
+ return Subclass::HasElementImpl(holder->GetIsolate(), holder, index, |
+ backing_store, filter); |
} |
- static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, |
+ static bool HasElementImpl(Isolate* isolate, Handle<JSObject> holder, |
+ uint32_t index, |
Handle<FixedArrayBase> backing_store, |
PropertyFilter filter) { |
- return Subclass::GetEntryForIndexImpl(*holder, *backing_store, index, |
- filter) != kMaxUInt32; |
+ return Subclass::GetEntryForIndexImpl(isolate, *holder, *backing_store, |
+ index, filter) != kMaxUInt32; |
} |
bool HasAccessors(JSObject* holder) final { |
@@ -772,6 +776,15 @@ class ElementsAccessorBase : public ElementsAccessor { |
JSObject::ValidateElements(array); |
} |
+ uint32_t NumberOfElements(JSObject* receiver) final { |
+ return Subclass::NumberOfElementsImpl(receiver, receiver->elements()); |
+ } |
+ |
+ static uint32_t NumberOfElementsImpl(JSObject* receiver, |
+ FixedArrayBase* backing_store) { |
+ UNREACHABLE(); |
+ } |
+ |
static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { |
if (receiver->IsJSArray()) { |
DCHECK(JSArray::cast(receiver)->length()->IsSmi()); |
@@ -1015,7 +1028,7 @@ class ElementsAccessorBase : public ElementsAccessor { |
if (!key->ToUint32(&index)) continue; |
uint32_t entry = Subclass::GetEntryForIndexImpl( |
- *object, object->elements(), index, filter); |
+ isolate, *object, object->elements(), index, filter); |
if (entry == kMaxUInt32) continue; |
PropertyDetails details = Subclass::GetDetailsImpl(*object, entry); |
@@ -1051,9 +1064,10 @@ class ElementsAccessorBase : public ElementsAccessor { |
// Non-dictionary elements can't have all-can-read accessors. |
uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); |
PropertyFilter filter = keys->filter(); |
- Factory* factory = keys->isolate()->factory(); |
+ Isolate* isolate = keys->isolate(); |
+ Factory* factory = isolate->factory(); |
for (uint32_t i = 0; i < length; i++) { |
- if (Subclass::HasElementImpl(object, i, backing_store, filter)) { |
+ if (Subclass::HasElementImpl(isolate, object, i, backing_store, filter)) { |
keys->AddKey(factory->NewNumberFromUint(i)); |
} |
} |
@@ -1066,7 +1080,7 @@ class ElementsAccessorBase : public ElementsAccessor { |
uint32_t insertion_index = 0) { |
uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); |
for (uint32_t i = 0; i < length; i++) { |
- if (Subclass::HasElementImpl(object, i, backing_store, filter)) { |
+ if (Subclass::HasElementImpl(isolate, object, i, backing_store, filter)) { |
if (convert == GetKeysConversion::kConvertToString) { |
Handle<String> index_string = isolate->factory()->Uint32ToString(i); |
list->set(insertion_index, *index_string); |
@@ -1096,6 +1110,7 @@ class ElementsAccessorBase : public ElementsAccessor { |
uint32_t nof_property_keys = keys->length(); |
uint32_t initial_list_length = |
Subclass::GetMaxNumberOfEntries(*object, *backing_store); |
+ |
initial_list_length += nof_property_keys; |
if (initial_list_length > FixedArray::kMaxLength || |
initial_list_length < nof_property_keys) { |
@@ -1103,13 +1118,30 @@ class ElementsAccessorBase : public ElementsAccessor { |
MessageTemplate::kInvalidArrayLength)); |
} |
- bool needs_sorting = |
- IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind()); |
- |
// Collect the element indices into a new list. |
+ MaybeHandle<FixedArray> raw_array = |
+ isolate->factory()->TryNewFixedArray(initial_list_length); |
+ Handle<FixedArray> combined_keys; |
+ |
+ // If we have a holey backing store try to precisely estimate the backing |
+ // store size as a last emergency measure if we cannot allocate the big |
+ // array. |
+ if (!raw_array.ToHandle(&combined_keys)) { |
+ if (IsHoleyElementsKind(kind())) { |
+ // If we overestimate the result list size we might end up in the |
+ // large-object space which doesn't free memory on shrinking the list. |
+ // Hence we try to estimate the final size for holey backing stores more |
+ // precisely here. |
+ initial_list_length = |
+ Subclass::NumberOfElementsImpl(*object, *backing_store); |
+ initial_list_length += nof_property_keys; |
+ } |
+ combined_keys = isolate->factory()->NewFixedArray(initial_list_length); |
+ } |
+ |
uint32_t nof_indices = 0; |
- Handle<FixedArray> combined_keys = |
- isolate->factory()->NewFixedArray(initial_list_length); |
+ bool needs_sorting = |
+ IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind()); |
combined_keys = Subclass::DirectCollectElementIndicesImpl( |
isolate, object, backing_store, |
needs_sorting ? GetKeysConversion::kKeepNumbers : convert, filter, |
@@ -1192,13 +1224,14 @@ class ElementsAccessorBase : public ElementsAccessor { |
return entry; |
} |
- static uint32_t GetEntryForIndexImpl(JSObject* holder, |
+ static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, |
FixedArrayBase* backing_store, |
uint32_t index, PropertyFilter filter) { |
uint32_t length = Subclass::GetMaxIndex(holder, backing_store); |
if (IsHoleyElementsKind(kind())) { |
return index < length && |
- !BackingStore::cast(backing_store)->is_the_hole(index) |
+ !BackingStore::cast(backing_store) |
+ ->is_the_hole(isolate, index) |
? index |
: kMaxUInt32; |
} else { |
@@ -1206,9 +1239,10 @@ class ElementsAccessorBase : public ElementsAccessor { |
} |
} |
- uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store, |
+ uint32_t GetEntryForIndex(Isolate* isolate, JSObject* holder, |
+ FixedArrayBase* backing_store, |
uint32_t index) final { |
- return Subclass::GetEntryForIndexImpl(holder, backing_store, index, |
+ return Subclass::GetEntryForIndexImpl(isolate, holder, backing_store, index, |
ALL_PROPERTIES); |
} |
@@ -1245,6 +1279,11 @@ class DictionaryElementsAccessor |
static uint32_t GetMaxNumberOfEntries(JSObject* receiver, |
FixedArrayBase* backing_store) { |
+ return NumberOfElementsImpl(receiver, backing_store); |
+ } |
+ |
+ static uint32_t NumberOfElementsImpl(JSObject* receiver, |
+ FixedArrayBase* backing_store) { |
SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); |
return dict->NumberOfElements(); |
} |
@@ -1393,11 +1432,12 @@ class DictionaryElementsAccessor |
object->set_elements(*new_dictionary); |
} |
- static bool HasEntryImpl(FixedArrayBase* store, uint32_t entry) { |
+ static bool HasEntryImpl(Isolate* isolate, FixedArrayBase* store, |
+ uint32_t entry) { |
DisallowHeapAllocation no_gc; |
SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
Object* index = dict->KeyAt(entry); |
- return !index->IsTheHole(dict->GetIsolate()); |
+ return !index->IsTheHole(isolate); |
} |
static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { |
@@ -1408,11 +1448,12 @@ class DictionaryElementsAccessor |
return result; |
} |
- static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store, |
- uint32_t index, PropertyFilter filter) { |
+ static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, |
+ FixedArrayBase* store, uint32_t index, |
+ PropertyFilter filter) { |
DisallowHeapAllocation no_gc; |
SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); |
- int entry = dictionary->FindEntry(index); |
+ int entry = dictionary->FindEntry(isolate, index); |
if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32; |
if (filter != ALL_PROPERTIES) { |
PropertyDetails details = dictionary->DetailsAt(entry); |
@@ -1508,8 +1549,8 @@ class DictionaryElementsAccessor |
Isolate* isolate = accumulator->isolate(); |
Handle<Object> undefined = isolate->factory()->undefined_value(); |
Handle<Object> the_hole = isolate->factory()->the_hole_value(); |
- SeededNumberDictionary* dictionary = |
- SeededNumberDictionary::cast(receiver->elements()); |
+ Handle<SeededNumberDictionary> dictionary( |
+ SeededNumberDictionary::cast(receiver->elements()), isolate); |
int capacity = dictionary->Capacity(); |
for (int i = 0; i < capacity; i++) { |
Object* k = dictionary->KeyAt(i); |
@@ -1729,7 +1770,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { |
int j = 0; |
for (int i = 0; j < capacity; i++) { |
if (IsHoleyElementsKind(kind)) { |
- if (BackingStore::cast(*store)->is_the_hole(i)) continue; |
+ if (BackingStore::cast(*store)->is_the_hole(isolate, i)) continue; |
} |
Handle<Object> value = Subclass::GetImpl(*store, i); |
dictionary = SeededNumberDictionary::AddNumberEntry( |
@@ -1742,12 +1783,12 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { |
static void DeleteAtEnd(Handle<JSObject> obj, |
Handle<BackingStore> backing_store, uint32_t entry) { |
uint32_t length = static_cast<uint32_t>(backing_store->length()); |
- Heap* heap = obj->GetHeap(); |
+ Isolate* isolate = obj->GetIsolate(); |
for (; entry > 0; entry--) { |
- if (!backing_store->is_the_hole(entry - 1)) break; |
+ if (!backing_store->is_the_hole(isolate, entry - 1)) break; |
} |
if (entry == 0) { |
- FixedArray* empty = heap->empty_fixed_array(); |
+ FixedArray* empty = isolate->heap()->empty_fixed_array(); |
// Dynamically ask for the elements kind here since we manually redirect |
// the operations for argument backing stores. |
if (obj->GetElementsKind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS) { |
@@ -1758,8 +1799,8 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { |
return; |
} |
- heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(*backing_store, |
- length - entry); |
+ isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( |
+ *backing_store, length - entry); |
} |
static void DeleteCommon(Handle<JSObject> obj, uint32_t entry, |
@@ -1774,6 +1815,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { |
return; |
} |
+ Isolate* isolate = obj->GetIsolate(); |
backing_store->set_the_hole(entry); |
// TODO(verwaest): Move this out of elements.cc. |
@@ -1790,12 +1832,13 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { |
} else { |
length = static_cast<uint32_t>(store->length()); |
} |
- if ((entry > 0 && backing_store->is_the_hole(entry - 1)) || |
- (entry + 1 < length && backing_store->is_the_hole(entry + 1))) { |
+ if ((entry > 0 && backing_store->is_the_hole(isolate, entry - 1)) || |
+ (entry + 1 < length && |
+ backing_store->is_the_hole(isolate, entry + 1))) { |
if (!obj->IsJSArray()) { |
uint32_t i; |
for (i = entry + 1; i < length; i++) { |
- if (!backing_store->is_the_hole(i)) break; |
+ if (!backing_store->is_the_hole(isolate, i)) break; |
} |
if (i == length) { |
DeleteAtEnd(obj, backing_store, entry); |
@@ -1804,7 +1847,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { |
} |
int num_used = 0; |
for (int i = 0; i < backing_store->length(); ++i) { |
- if (!backing_store->is_the_hole(i)) { |
+ if (!backing_store->is_the_hole(isolate, i)) { |
++num_used; |
// Bail out if a number dictionary wouldn't be able to save at least |
// 75% space. |
@@ -1865,19 +1908,32 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { |
DeleteCommon(obj, entry, handle(obj->elements())); |
} |
- static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) { |
- return !BackingStore::cast(backing_store)->is_the_hole(entry); |
+ static bool HasEntryImpl(Isolate* isolate, FixedArrayBase* backing_store, |
+ uint32_t entry) { |
+ return !BackingStore::cast(backing_store)->is_the_hole(isolate, entry); |
+ } |
+ |
+ static uint32_t NumberOfElementsImpl(JSObject* receiver, |
+ FixedArrayBase* backing_store) { |
+ uint32_t max_index = Subclass::GetMaxIndex(receiver, backing_store); |
+ if (IsFastPackedElementsKind(Subclass::kind())) return max_index; |
+ Isolate* isolate = receiver->GetIsolate(); |
+ uint32_t count = 0; |
+ for (uint32_t i = 0; i < max_index; i++) { |
+ if (Subclass::HasEntryImpl(isolate, backing_store, i)) count++; |
+ } |
+ return count; |
} |
static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
KeyAccumulator* accumulator, |
AddKeyConversion convert) { |
- Handle<FixedArrayBase> elements(receiver->elements(), |
- accumulator->isolate()); |
+ Isolate* isolate = accumulator->isolate(); |
+ Handle<FixedArrayBase> elements(receiver->elements(), isolate); |
uint32_t length = Subclass::GetMaxNumberOfEntries(*receiver, *elements); |
for (uint32_t i = 0; i < length; i++) { |
if (IsFastPackedElementsKind(KindTraits::Kind) || |
- HasEntryImpl(*elements, i)) { |
+ HasEntryImpl(isolate, *elements, i)) { |
accumulator->AddKey(Subclass::GetImpl(*elements, i), convert); |
} |
} |
@@ -1906,12 +1962,12 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { |
for (int i = 0; i < length; i++) { |
DCHECK(BackingStore::get(*backing_store, i, isolate)->IsSmi() || |
(IsFastHoleyElementsKind(KindTraits::Kind) && |
- backing_store->is_the_hole(i))); |
+ backing_store->is_the_hole(isolate, i))); |
} |
} else if (KindTraits::Kind == FAST_ELEMENTS || |
KindTraits::Kind == FAST_DOUBLE_ELEMENTS) { |
for (int i = 0; i < length; i++) { |
- DCHECK(!backing_store->is_the_hole(i)); |
+ DCHECK(!backing_store->is_the_hole(isolate, i)); |
} |
} else { |
DCHECK(IsFastHoleyElementsKind(KindTraits::Kind)); |
@@ -2013,11 +2069,13 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { |
Isolate* isolate, Handle<JSObject> object, |
Handle<FixedArray> values_or_entries, bool get_entries, int* nof_items, |
PropertyFilter filter) { |
+ Handle<BackingStore> elements(BackingStore::cast(object->elements()), |
+ isolate); |
int count = 0; |
- uint32_t length = object->elements()->length(); |
+ uint32_t length = elements->length(); |
for (uint32_t index = 0; index < length; ++index) { |
- if (!HasEntryImpl(object->elements(), index)) continue; |
- Handle<Object> value = Subclass::GetImpl(object->elements(), index); |
+ if (!HasEntryImpl(isolate, *elements, index)) continue; |
+ Handle<Object> value = Subclass::GetImpl(*elements, index); |
if (get_entries) { |
value = MakeEntryPair(isolate, index, value); |
} |
@@ -2357,7 +2415,6 @@ class FastSmiOrObjectElementsAccessor |
return backing_store->get(index); |
} |
- |
// NOTE: this method violates the handlified function signature convention: |
// raw pointer parameters in the function that allocates. |
// See ElementsAccessor::CopyElements() for details. |
@@ -2656,7 +2713,8 @@ class TypedElementsAccessor |
return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); |
} |
- static bool HasElementImpl(Handle<JSObject> holder, uint32_t index, |
+ static bool HasElementImpl(Isolate* isolate, Handle<JSObject> holder, |
+ uint32_t index, |
Handle<FixedArrayBase> backing_store, |
PropertyFilter filter) { |
return index < AccessorClass::GetCapacityImpl(*holder, *backing_store); |
@@ -2683,7 +2741,7 @@ class TypedElementsAccessor |
return entry; |
} |
- static uint32_t GetEntryForIndexImpl(JSObject* holder, |
+ static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, |
FixedArrayBase* backing_store, |
uint32_t index, PropertyFilter filter) { |
return index < AccessorClass::GetCapacityImpl(holder, backing_store) |
@@ -2698,6 +2756,11 @@ class TypedElementsAccessor |
return backing_store->length(); |
} |
+ static uint32_t NumberOfElementsImpl(JSObject* receiver, |
+ FixedArrayBase* backing_store) { |
+ return AccessorClass::GetCapacityImpl(receiver, backing_store); |
+ } |
+ |
static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
KeyAccumulator* accumulator, |
AddKeyConversion convert) { |
@@ -2936,19 +2999,34 @@ class SloppyArgumentsElementsAccessor |
ArgumentsAccessor::GetMaxNumberOfEntries(holder, arguments); |
} |
+ static uint32_t NumberOfElementsImpl(JSObject* receiver, |
+ FixedArrayBase* backing_store) { |
+ FixedArray* parameter_map = FixedArray::cast(backing_store); |
+ FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
+ uint32_t nof_elements = 0; |
+ uint32_t length = parameter_map->length() - 2; |
+ for (uint32_t entry = 0; entry < length; entry++) { |
+ if (HasParameterMapArg(parameter_map, entry)) nof_elements++; |
+ } |
+ return nof_elements + |
+ ArgumentsAccessor::NumberOfElementsImpl(receiver, arguments); |
+ } |
+ |
static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
KeyAccumulator* accumulator, |
AddKeyConversion convert) { |
- FixedArrayBase* elements = receiver->elements(); |
- uint32_t length = GetCapacityImpl(*receiver, elements); |
+ Isolate* isolate = accumulator->isolate(); |
+ Handle<FixedArrayBase> elements(receiver->elements(), isolate); |
+ uint32_t length = GetCapacityImpl(*receiver, *elements); |
for (uint32_t entry = 0; entry < length; entry++) { |
- if (!HasEntryImpl(elements, entry)) continue; |
- Handle<Object> value = GetImpl(elements, entry); |
+ if (!HasEntryImpl(isolate, *elements, entry)) continue; |
+ Handle<Object> value = GetImpl(*elements, entry); |
accumulator->AddKey(value, convert); |
} |
} |
- static bool HasEntryImpl(FixedArrayBase* parameters, uint32_t entry) { |
+ static bool HasEntryImpl(Isolate* isolate, FixedArrayBase* parameters, |
+ uint32_t entry) { |
FixedArray* parameter_map = FixedArray::cast(parameters); |
uint32_t length = parameter_map->length() - 2; |
if (entry < length) { |
@@ -2956,7 +3034,7 @@ class SloppyArgumentsElementsAccessor |
} |
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
- return ArgumentsAccessor::HasEntryImpl(arguments, entry - length); |
+ return ArgumentsAccessor::HasEntryImpl(isolate, arguments, entry - length); |
} |
static bool HasAccessorsImpl(JSObject* holder, |
@@ -2976,15 +3054,15 @@ class SloppyArgumentsElementsAccessor |
return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); |
} |
- static uint32_t GetEntryForIndexImpl(JSObject* holder, |
+ static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, |
FixedArrayBase* parameters, |
uint32_t index, PropertyFilter filter) { |
FixedArray* parameter_map = FixedArray::cast(parameters); |
if (HasParameterMapArg(parameter_map, index)) return index; |
FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
- uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, |
- index, filter); |
+ uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl( |
+ isolate, holder, arguments, index, filter); |
if (entry == kMaxUInt32) return kMaxUInt32; |
return (parameter_map->length() - 2) + entry; |
} |
@@ -3071,8 +3149,8 @@ class SloppyArgumentsElementsAccessor |
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); |
+ uint32_t entry = GetEntryForIndexImpl(isolate, *object, *parameter_map, k, |
+ ALL_PROPERTIES); |
if (entry == kMaxUInt32) { |
if (search_for_hole) return Just(true); |
continue; |
@@ -3111,8 +3189,8 @@ class SloppyArgumentsElementsAccessor |
isolate); |
for (uint32_t k = start_from; k < length; ++k) { |
- uint32_t entry = |
- GetEntryForIndexImpl(*object, *parameter_map, k, ALL_PROPERTIES); |
+ uint32_t entry = GetEntryForIndexImpl(isolate, *object, *parameter_map, k, |
+ ALL_PROPERTIES); |
if (entry == kMaxUInt32) { |
continue; |
} |
@@ -3259,9 +3337,9 @@ class FastSloppyArgumentsElementsAccessor |
FixedArray* parameters = FixedArray::cast(receiver->elements()); |
uint32_t insertion_index = 0; |
for (uint32_t i = start; i < end; i++) { |
- uint32_t entry = |
- GetEntryForIndexImpl(*receiver, parameters, i, ALL_PROPERTIES); |
- if (entry != kMaxUInt32 && HasEntryImpl(parameters, entry)) { |
+ uint32_t entry = GetEntryForIndexImpl(isolate, *receiver, parameters, i, |
+ ALL_PROPERTIES); |
+ if (entry != kMaxUInt32 && HasEntryImpl(isolate, parameters, entry)) { |
elements->set(insertion_index, *GetImpl(parameters, entry)); |
} else { |
elements->set_the_hole(insertion_index); |
@@ -3384,13 +3462,13 @@ class StringWrapperElementsAccessor |
return BackingStoreAccessor::GetDetailsImpl(holder, entry - length); |
} |
- static uint32_t GetEntryForIndexImpl(JSObject* holder, |
+ static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject* holder, |
FixedArrayBase* backing_store, |
uint32_t index, PropertyFilter filter) { |
uint32_t length = static_cast<uint32_t>(GetString(holder)->length()); |
if (index < length) return index; |
uint32_t backing_store_entry = BackingStoreAccessor::GetEntryForIndexImpl( |
- holder, backing_store, index, filter); |
+ isolate, holder, backing_store, index, filter); |
if (backing_store_entry == kMaxUInt32) return kMaxUInt32; |
DCHECK(backing_store_entry < kMaxUInt32 - length); |
return backing_store_entry + length; |
@@ -3497,6 +3575,13 @@ class StringWrapperElementsAccessor |
} |
} |
+ static uint32_t NumberOfElementsImpl(JSObject* object, |
+ FixedArrayBase* backing_store) { |
+ uint32_t length = GetString(object)->length(); |
+ return length + |
+ BackingStoreAccessor::NumberOfElementsImpl(object, backing_store); |
+ } |
+ |
private: |
static String* GetString(JSObject* holder) { |
DCHECK(holder->IsJSValue()); |