@@ -445,6 +445,26 @@ static void TraceTopFrame(Isolate* isolate) {
445445 JavaScriptFrame::PrintTop (isolate, stdout, false , true );
446446}
447447
448+ static void SortIndices (
449+ Handle<FixedArray> indices, uint32_t sort_size,
450+ WriteBarrierMode write_barrier_mode = UPDATE_WRITE_BARRIER ) {
451+ struct {
452+ bool operator ()(Object* a, Object* b) {
453+ if (!a->IsUndefined ()) {
454+ if (b->IsUndefined ()) return true ;
455+ return a->Number () < b->Number ();
456+ }
457+ return b->IsUndefined ();
458+ }
459+ } cmp;
460+ Object** start =
461+ reinterpret_cast <Object**>(indices->GetFirstElementAddress ());
462+ std::sort (start, start + sort_size, cmp);
463+ if (write_barrier_mode != SKIP_WRITE_BARRIER ) {
464+ FIXED_ARRAY_ELEMENTS_WRITE_BARRIER (indices->GetIsolate ()->heap (), *indices,
465+ 0 , sort_size);
466+ }
467+ }
448468
449469// Base class for element handler implementations. Contains the
450470// the common logic for objects with different ElementsKinds.
@@ -709,8 +729,7 @@ class ElementsAccessorBase : public ElementsAccessor {
709729 JSObject::ValidateElements (array);
710730 }
711731
712- static uint32_t GetIterationLength (JSObject* receiver,
713- FixedArrayBase* elements) {
732+ static uint32_t GetMaxIndex (JSObject* receiver, FixedArrayBase* elements) {
714733 if (receiver->IsJSArray ()) {
715734 DCHECK (JSArray::cast (receiver)->length ()->IsSmi ());
716735 return static_cast <uint32_t >(
@@ -719,6 +738,11 @@ class ElementsAccessorBase : public ElementsAccessor {
719738 return Subclass::GetCapacityImpl (receiver, elements);
720739 }
721740
741+ static uint32_t GetMaxNumberOfEntries (JSObject* receiver,
742+ FixedArrayBase* elements) {
743+ return Subclass::GetMaxIndex (receiver, elements);
744+ }
745+
722746 static Handle<FixedArrayBase> ConvertElementsWithCapacity (
723747 Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
724748 ElementsKind from_kind, uint32_t capacity) {
@@ -863,7 +887,6 @@ class ElementsAccessorBase : public ElementsAccessor {
863887 PropertyFilter filter) {
864888 int count = 0 ;
865889 KeyAccumulator accumulator (isolate, OWN_ONLY , ALL_PROPERTIES );
866- accumulator.NextPrototype ();
867890 Subclass::CollectElementIndicesImpl (
868891 object, handle (object->elements (), isolate), &accumulator);
869892 Handle<FixedArray> keys = accumulator.GetKeys ();
@@ -909,11 +932,12 @@ class ElementsAccessorBase : public ElementsAccessor {
909932 KeyAccumulator* keys) {
910933 DCHECK_NE (DICTIONARY_ELEMENTS , kind ());
911934 // Non-dictionary elements can't have all-can-read accessors.
912- uint32_t length = GetIterationLength (*object, *backing_store);
935+ uint32_t length = Subclass::GetMaxIndex (*object, *backing_store);
913936 PropertyFilter filter = keys->filter ();
937+ Factory* factory = keys->isolate ()->factory ();
914938 for (uint32_t i = 0 ; i < length; i++) {
915939 if (Subclass::HasElementImpl (object, i, backing_store, filter)) {
916- keys->AddKey (i );
940+ keys->AddKey (factory-> NewNumberFromUint (i) );
917941 }
918942 }
919943 }
@@ -923,7 +947,7 @@ class ElementsAccessorBase : public ElementsAccessor {
923947 Handle<FixedArrayBase> backing_store, GetKeysConversion convert,
924948 PropertyFilter filter, Handle<FixedArray> list, uint32_t * nof_indices,
925949 uint32_t insertion_index = 0 ) {
926- uint32_t length = Subclass::GetIterationLength (*object, *backing_store);
950+ uint32_t length = Subclass::GetMaxIndex (*object, *backing_store);
927951 for (uint32_t i = 0 ; i < length; i++) {
928952 if (Subclass::HasElementImpl (object, i, backing_store, filter)) {
929953 if (convert == CONVERT_TO_STRING ) {
@@ -968,18 +992,7 @@ class ElementsAccessorBase : public ElementsAccessor {
968992
969993 // Sort the indices list if necessary.
970994 if (IsDictionaryElementsKind (kind ()) || IsSloppyArgumentsElements (kind ())) {
971- struct {
972- bool operator ()(Object* a, Object* b) {
973- if (!a->IsUndefined ()) {
974- if (b->IsUndefined ()) return true ;
975- return a->Number () < b->Number ();
976- }
977- return !b->IsUndefined ();
978- }
979- } cmp;
980- Object** start =
981- reinterpret_cast <Object**>(combined_keys->GetFirstElementAddress ());
982- std::sort (start, start + nof_indices, cmp);
995+ SortIndices (combined_keys, nof_indices, SKIP_WRITE_BARRIER );
983996 uint32_t array_length = 0 ;
984997 // Indices from dictionary elements should only be converted after
985998 // sorting.
@@ -1044,7 +1057,7 @@ class ElementsAccessorBase : public ElementsAccessor {
10441057 ? index
10451058 : kMaxUInt32 ;
10461059 } else {
1047- uint32_t length = GetIterationLength (holder, backing_store);
1060+ uint32_t length = Subclass::GetMaxIndex (holder, backing_store);
10481061 return index < length ? index : kMaxUInt32 ;
10491062 }
10501063 }
@@ -1081,17 +1094,15 @@ class DictionaryElementsAccessor
10811094 : ElementsAccessorBase<DictionaryElementsAccessor,
10821095 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
10831096
1084- static uint32_t GetIterationLength (JSObject* receiver,
1085- FixedArrayBase* elements) {
1086- uint32_t length;
1087- if (receiver->IsJSArray ()) {
1088- // Special-case GetIterationLength for dictionary elements since the
1089- // length of the array might be a HeapNumber.
1090- JSArray::cast (receiver)->length ()->ToArrayLength (&length);
1091- } else {
1092- length = GetCapacityImpl (receiver, elements);
1093- }
1094- return length;
1097+ static uint32_t GetMaxIndex (JSObject* receiver, FixedArrayBase* elements) {
1098+ // We cannot properly estimate this for dictionaries.
1099+ UNREACHABLE ();
1100+ }
1101+
1102+ static uint32_t GetMaxNumberOfEntries (JSObject* receiver,
1103+ FixedArrayBase* backing_store) {
1104+ SeededNumberDictionary* dict = SeededNumberDictionary::cast (backing_store);
1105+ return dict->NumberOfElements ();
10951106 }
10961107
10971108 static void SetLengthImpl (Isolate* isolate, Handle<JSArray> array,
@@ -1313,21 +1324,27 @@ class DictionaryElementsAccessor
13131324 Handle<FixedArrayBase> backing_store,
13141325 KeyAccumulator* keys) {
13151326 if (keys->filter () & SKIP_STRINGS ) return ;
1316- Isolate* isolate = keys->isolate ();
1317- Handle<Object> undefined = isolate-> factory () ->undefined_value ();
1318- Handle<Object> the_hole = isolate-> factory () ->the_hole_value ();
1327+ Factory* factory = keys->isolate ()-> factory ();
1328+ Handle<Object> undefined = factory->undefined_value ();
1329+ Handle<Object> the_hole = factory->the_hole_value ();
13191330 Handle<SeededNumberDictionary> dictionary =
13201331 Handle<SeededNumberDictionary>::cast (backing_store);
13211332 int capacity = dictionary->Capacity ();
1333+ Handle<FixedArray> elements =
1334+ factory->NewFixedArray (GetMaxNumberOfEntries (*object, *backing_store));
1335+ int insertion_index = 0 ;
13221336 PropertyFilter filter = keys->filter ();
13231337 for (int i = 0 ; i < capacity; i++) {
13241338 uint32_t key =
13251339 GetKeyForEntryImpl (dictionary, i, filter, *undefined, *the_hole);
13261340 if (key == kMaxUInt32 ) continue ;
1327- keys->AddKey (key);
1341+ elements->set (insertion_index, *factory->NewNumberFromUint (key));
1342+ insertion_index++;
1343+ }
1344+ SortIndices (elements, insertion_index);
1345+ for (int i = 0 ; i < insertion_index; i++) {
1346+ keys->AddKey (elements->get (i));
13281347 }
1329-
1330- keys->SortCurrentElementsList ();
13311348 }
13321349
13331350 static Handle<FixedArray> DirectCollectElementIndicesImpl (
@@ -1552,8 +1569,8 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
15521569 KeyAccumulator* accumulator,
15531570 AddKeyConversion convert) {
15541571 Handle<FixedArrayBase> elements (receiver->elements (),
1555- receiver-> GetIsolate ());
1556- uint32_t length = Subclass::GetIterationLength (*receiver, *elements);
1572+ accumulator-> isolate ());
1573+ uint32_t length = Subclass::GetMaxNumberOfEntries (*receiver, *elements);
15571574 for (uint32_t i = 0 ; i < length; i++) {
15581575 if (IsFastPackedElementsKind (KindTraits::Kind) ||
15591576 HasEntryImpl (*elements, i)) {
@@ -2386,18 +2403,16 @@ class SloppyArgumentsElementsAccessor
23862403 static void CollectElementIndicesImpl (Handle<JSObject> object,
23872404 Handle<FixedArrayBase> backing_store,
23882405 KeyAccumulator* keys) {
2389- FixedArray* parameter_map = FixedArray::cast (*backing_store);
2390- uint32_t length = parameter_map->length () - 2 ;
2391- for (uint32_t i = 0 ; i < length; ++i) {
2392- if (!parameter_map->get (i + 2 )->IsTheHole ()) {
2393- keys->AddKey (i);
2394- }
2395- }
2396-
2397- Handle<FixedArrayBase> store (FixedArrayBase::cast (parameter_map->get (1 )));
2398- ArgumentsAccessor::CollectElementIndicesImpl (object, store, keys);
2399- if (Subclass::kind () == FAST_SLOPPY_ARGUMENTS_ELEMENTS ) {
2400- keys->SortCurrentElementsList ();
2406+ Isolate* isolate = keys->isolate ();
2407+ uint32_t nof_indices = 0 ;
2408+ Handle<FixedArray> indices = isolate->factory ()->NewFixedArray (
2409+ GetCapacityImpl (*object, *backing_store));
2410+ DirectCollectElementIndicesImpl (isolate, object, backing_store,
2411+ KEEP_NUMBERS , ENUMERABLE_STRINGS , indices,
2412+ &nof_indices);
2413+ SortIndices (indices, nof_indices);
2414+ for (uint32_t i = 0 ; i < nof_indices; i++) {
2415+ keys->AddKey (indices->get (i));
24012416 }
24022417 }
24032418
@@ -2745,8 +2760,9 @@ class StringWrapperElementsAccessor
27452760 Handle<FixedArrayBase> backing_store,
27462761 KeyAccumulator* keys) {
27472762 uint32_t length = GetString (*object)->length ();
2763+ Factory* factory = keys->isolate ()->factory ();
27482764 for (uint32_t i = 0 ; i < length; i++) {
2749- keys->AddKey (i );
2765+ keys->AddKey (factory-> NewNumberFromUint (i) );
27502766 }
27512767 BackingStoreAccessor::CollectElementIndicesImpl (object, backing_store,
27522768 keys);
0 commit comments