Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index b27aec3ee2ef4a6973c826119bf5f3f33f969047..6c257ac63f3424b4dd531d1c936e0ff12e38bebd 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -445,26 +445,6 @@ |
JavaScriptFrame::PrintTop(isolate, stdout, false, true); |
} |
-static void SortIndices( |
- Handle<FixedArray> indices, uint32_t sort_size, |
- WriteBarrierMode write_barrier_mode = UPDATE_WRITE_BARRIER) { |
- struct { |
- bool operator()(Object* a, Object* b) { |
- if (!a->IsUndefined()) { |
- if (b->IsUndefined()) return true; |
- return a->Number() < b->Number(); |
- } |
- return b->IsUndefined(); |
- } |
- } cmp; |
- Object** start = |
- reinterpret_cast<Object**>(indices->GetFirstElementAddress()); |
- std::sort(start, start + sort_size, cmp); |
- if (write_barrier_mode != SKIP_WRITE_BARRIER) { |
- FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(indices->GetIsolate()->heap(), *indices, |
- 0, sort_size); |
- } |
-} |
// Base class for element handler implementations. Contains the |
// the common logic for objects with different ElementsKinds. |
@@ -729,18 +709,14 @@ |
JSObject::ValidateElements(array); |
} |
- static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { |
+ static uint32_t GetIterationLength(JSObject* receiver, |
+ FixedArrayBase* elements) { |
if (receiver->IsJSArray()) { |
DCHECK(JSArray::cast(receiver)->length()->IsSmi()); |
return static_cast<uint32_t>( |
Smi::cast(JSArray::cast(receiver)->length())->value()); |
} |
return Subclass::GetCapacityImpl(receiver, elements); |
- } |
- |
- static uint32_t GetMaxNumberOfEntries(JSObject* receiver, |
- FixedArrayBase* elements) { |
- return Subclass::GetMaxIndex(receiver, elements); |
} |
static Handle<FixedArrayBase> ConvertElementsWithCapacity( |
@@ -887,6 +863,7 @@ |
PropertyFilter filter) { |
int count = 0; |
KeyAccumulator accumulator(isolate, OWN_ONLY, ALL_PROPERTIES); |
+ accumulator.NextPrototype(); |
Subclass::CollectElementIndicesImpl( |
object, handle(object->elements(), isolate), &accumulator); |
Handle<FixedArray> keys = accumulator.GetKeys(); |
@@ -932,12 +909,11 @@ |
KeyAccumulator* keys) { |
DCHECK_NE(DICTIONARY_ELEMENTS, kind()); |
// Non-dictionary elements can't have all-can-read accessors. |
- uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); |
+ uint32_t length = GetIterationLength(*object, *backing_store); |
PropertyFilter filter = keys->filter(); |
- Factory* factory = keys->isolate()->factory(); |
for (uint32_t i = 0; i < length; i++) { |
if (Subclass::HasElementImpl(object, i, backing_store, filter)) { |
- keys->AddKey(factory->NewNumberFromUint(i)); |
+ keys->AddKey(i); |
} |
} |
} |
@@ -947,7 +923,7 @@ |
Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
uint32_t insertion_index = 0) { |
- uint32_t length = Subclass::GetMaxIndex(*object, *backing_store); |
+ uint32_t length = Subclass::GetIterationLength(*object, *backing_store); |
for (uint32_t i = 0; i < length; i++) { |
if (Subclass::HasElementImpl(object, i, backing_store, filter)) { |
if (convert == CONVERT_TO_STRING) { |
@@ -992,7 +968,18 @@ |
// Sort the indices list if necessary. |
if (IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind())) { |
- SortIndices(combined_keys, nof_indices, SKIP_WRITE_BARRIER); |
+ struct { |
+ bool operator()(Object* a, Object* b) { |
+ if (!a->IsUndefined()) { |
+ if (b->IsUndefined()) return true; |
+ return a->Number() < b->Number(); |
+ } |
+ return !b->IsUndefined(); |
+ } |
+ } cmp; |
+ Object** start = |
+ reinterpret_cast<Object**>(combined_keys->GetFirstElementAddress()); |
+ std::sort(start, start + nof_indices, cmp); |
uint32_t array_length = 0; |
// Indices from dictionary elements should only be converted after |
// sorting. |
@@ -1057,7 +1044,7 @@ |
? index |
: kMaxUInt32; |
} else { |
- uint32_t length = Subclass::GetMaxIndex(holder, backing_store); |
+ uint32_t length = GetIterationLength(holder, backing_store); |
return index < length ? index : kMaxUInt32; |
} |
} |
@@ -1094,15 +1081,17 @@ |
: ElementsAccessorBase<DictionaryElementsAccessor, |
ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} |
- static uint32_t GetMaxIndex(JSObject* receiver, FixedArrayBase* elements) { |
- // We cannot properly estimate this for dictionaries. |
- UNREACHABLE(); |
- } |
- |
- static uint32_t GetMaxNumberOfEntries(JSObject* receiver, |
- FixedArrayBase* backing_store) { |
- SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); |
- return dict->NumberOfElements(); |
+ static uint32_t GetIterationLength(JSObject* receiver, |
+ FixedArrayBase* elements) { |
+ uint32_t length; |
+ if (receiver->IsJSArray()) { |
+ // Special-case GetIterationLength for dictionary elements since the |
+ // length of the array might be a HeapNumber. |
+ JSArray::cast(receiver)->length()->ToArrayLength(&length); |
+ } else { |
+ length = GetCapacityImpl(receiver, elements); |
+ } |
+ return length; |
} |
static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
@@ -1324,27 +1313,21 @@ |
Handle<FixedArrayBase> backing_store, |
KeyAccumulator* keys) { |
if (keys->filter() & SKIP_STRINGS) return; |
- Factory* factory = keys->isolate()->factory(); |
- Handle<Object> undefined = factory->undefined_value(); |
- Handle<Object> the_hole = factory->the_hole_value(); |
+ Isolate* isolate = keys->isolate(); |
+ Handle<Object> undefined = isolate->factory()->undefined_value(); |
+ Handle<Object> the_hole = isolate->factory()->the_hole_value(); |
Handle<SeededNumberDictionary> dictionary = |
Handle<SeededNumberDictionary>::cast(backing_store); |
int capacity = dictionary->Capacity(); |
- Handle<FixedArray> elements = |
- factory->NewFixedArray(GetMaxNumberOfEntries(*object, *backing_store)); |
- int insertion_index = 0; |
PropertyFilter filter = keys->filter(); |
for (int i = 0; i < capacity; i++) { |
uint32_t key = |
GetKeyForEntryImpl(dictionary, i, filter, *undefined, *the_hole); |
if (key == kMaxUInt32) continue; |
- elements->set(insertion_index, *factory->NewNumberFromUint(key)); |
- insertion_index++; |
- } |
- SortIndices(elements, insertion_index); |
- for (int i = 0; i < insertion_index; i++) { |
- keys->AddKey(elements->get(i)); |
- } |
+ keys->AddKey(key); |
+ } |
+ |
+ keys->SortCurrentElementsList(); |
} |
static Handle<FixedArray> DirectCollectElementIndicesImpl( |
@@ -1569,8 +1552,8 @@ |
KeyAccumulator* accumulator, |
AddKeyConversion convert) { |
Handle<FixedArrayBase> elements(receiver->elements(), |
- accumulator->isolate()); |
- uint32_t length = Subclass::GetMaxNumberOfEntries(*receiver, *elements); |
+ receiver->GetIsolate()); |
+ uint32_t length = Subclass::GetIterationLength(*receiver, *elements); |
for (uint32_t i = 0; i < length; i++) { |
if (IsFastPackedElementsKind(KindTraits::Kind) || |
HasEntryImpl(*elements, i)) { |
@@ -2403,16 +2386,18 @@ |
static void CollectElementIndicesImpl(Handle<JSObject> object, |
Handle<FixedArrayBase> backing_store, |
KeyAccumulator* keys) { |
- Isolate* isolate = keys->isolate(); |
- uint32_t nof_indices = 0; |
- Handle<FixedArray> indices = isolate->factory()->NewFixedArray( |
- GetCapacityImpl(*object, *backing_store)); |
- DirectCollectElementIndicesImpl(isolate, object, backing_store, |
- KEEP_NUMBERS, ENUMERABLE_STRINGS, indices, |
- &nof_indices); |
- SortIndices(indices, nof_indices); |
- for (uint32_t i = 0; i < nof_indices; i++) { |
- keys->AddKey(indices->get(i)); |
+ FixedArray* parameter_map = FixedArray::cast(*backing_store); |
+ uint32_t length = parameter_map->length() - 2; |
+ for (uint32_t i = 0; i < length; ++i) { |
+ if (!parameter_map->get(i + 2)->IsTheHole()) { |
+ keys->AddKey(i); |
+ } |
+ } |
+ |
+ Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1))); |
+ ArgumentsAccessor::CollectElementIndicesImpl(object, store, keys); |
+ if (Subclass::kind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS) { |
+ keys->SortCurrentElementsList(); |
} |
} |
@@ -2760,9 +2745,8 @@ |
Handle<FixedArrayBase> backing_store, |
KeyAccumulator* keys) { |
uint32_t length = GetString(*object)->length(); |
- Factory* factory = keys->isolate()->factory(); |
for (uint32_t i = 0; i < length; i++) { |
- keys->AddKey(factory->NewNumberFromUint(i)); |
+ keys->AddKey(i); |
} |
BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, |
keys); |