Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index 6c257ac63f3424b4dd531d1c936e0ff12e38bebd..9f707bc400efbb3f428795e438cf1207ac640870 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -445,6 +445,25 @@ static void TraceTopFrame(Isolate* isolate) { |
JavaScriptFrame::PrintTop(isolate, stdout, false, true); |
} |
+static void SortIndices(Handle<FixedArray> indices, uint32_t sort_size, |
+ bool emit_write_barrier = true) { |
Jakob Kummerow
2016/05/23 16:25:21
Consider using the existing enum WriteBarrierMode
Camillo Bruni
2016/05/23 19:10:13
updated.
|
+ struct { |
+ bool operator()(Object* a, Object* b) { |
+ if (!a->IsUndefined()) { |
+ if (b->IsUndefined()) return true; |
+ return a->Number() < b->Number(); |
+ } |
+ return !b->IsUndefined(); |
Jakob Kummerow
2016/05/23 16:25:21
I'm pretty sure this condition is inverted, i.e. y
Camillo Bruni
2016/05/23 19:10:13
good catch!
you're right, if b is smaller than a r
|
+ } |
+ } cmp; |
+ Object** start = |
+ reinterpret_cast<Object**>(indices->GetFirstElementAddress()); |
+ std::sort(start, start + sort_size, cmp); |
+ if (emit_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. |
@@ -863,7 +882,6 @@ class ElementsAccessorBase : public ElementsAccessor { |
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(); |
@@ -911,9 +929,10 @@ class ElementsAccessorBase : public ElementsAccessor { |
// Non-dictionary elements can't have all-can-read accessors. |
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(i); |
+ keys->AddKey(factory->NewNumberFromUint(i)); |
} |
} |
} |
@@ -968,18 +987,7 @@ class ElementsAccessorBase : public ElementsAccessor { |
// Sort the indices list if necessary. |
if (IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind())) { |
- 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); |
+ SortIndices(combined_keys, nof_indices, false); |
uint32_t array_length = 0; |
// Indices from dictionary elements should only be converted after |
// sorting. |
@@ -1082,16 +1090,9 @@ class DictionaryElementsAccessor |
ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} |
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; |
+ FixedArrayBase* backing_store) { |
+ SeededNumberDictionary* dict = SeededNumberDictionary::cast(backing_store); |
+ return dict->NumberOfElements(); |
Jakob Kummerow
2016/05/23 16:25:21
In existing code, GetIterationLength is clearly ex
Camillo Bruni
2016/05/23 19:10:13
Renamed to GetMaxNumberOfElements, though the rest
|
} |
static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
@@ -1313,21 +1314,27 @@ class DictionaryElementsAccessor |
Handle<FixedArrayBase> backing_store, |
KeyAccumulator* keys) { |
if (keys->filter() & SKIP_STRINGS) return; |
- Isolate* isolate = keys->isolate(); |
- Handle<Object> undefined = isolate->factory()->undefined_value(); |
- Handle<Object> the_hole = isolate->factory()->the_hole_value(); |
+ Factory* factory = keys->isolate()->factory(); |
+ Handle<Object> undefined = factory->undefined_value(); |
+ Handle<Object> the_hole = factory->the_hole_value(); |
Handle<SeededNumberDictionary> dictionary = |
Handle<SeededNumberDictionary>::cast(backing_store); |
int capacity = dictionary->Capacity(); |
+ Handle<FixedArray> elements = |
+ factory->NewFixedArray(GetIterationLength(*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; |
- keys->AddKey(key); |
+ 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->SortCurrentElementsList(); |
} |
static Handle<FixedArray> DirectCollectElementIndicesImpl( |
@@ -2386,18 +2393,16 @@ class SloppyArgumentsElementsAccessor |
static void CollectElementIndicesImpl(Handle<JSObject> object, |
Handle<FixedArrayBase> backing_store, |
KeyAccumulator* keys) { |
- 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(); |
+ 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)); |
} |
} |
@@ -2745,8 +2750,9 @@ class StringWrapperElementsAccessor |
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(i); |
+ keys->AddKey(factory->NewNumberFromUint(i)); |
} |
BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, |
keys); |