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

Unified Diff: src/elements.cc

Issue 2041963003: [elements] Precisely estimate elements size for large-object limits (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: add missing method on string wrapper Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/elements.h ('k') | src/factory.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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());
« 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