| 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);
|
|
|