Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 9a903f1ff59ad217d25a74e53589927ea1d12ff7..02be037d0810df37d11848f8b029acef7c4636a2 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -6009,7 +6009,7 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object, |
iteration_order = |
NameDictionary::DoGenerateNewEnumerationIndices(dictionary); |
} else { |
- iteration_order = NameDictionary::BuildIterationIndicesArray(dictionary); |
+ iteration_order = NameDictionary::IterationIndices(dictionary); |
} |
int instance_descriptor_length = iteration_order->length(); |
@@ -16259,118 +16259,6 @@ int FixedArrayBase::GetMaxLengthForNewSpaceAllocation(ElementsKind kind) { |
ElementsKindToShiftSize(kind)); |
} |
-void FixedArray::SwapPairs(FixedArray* numbers, int i, int j) { |
- Object* temp = get(i); |
- set(i, get(j)); |
- set(j, temp); |
- if (this != numbers) { |
- temp = numbers->get(i); |
- numbers->set(i, Smi::cast(numbers->get(j))); |
- numbers->set(j, Smi::cast(temp)); |
- } |
-} |
- |
- |
-static void InsertionSortPairs(FixedArray* content, |
- FixedArray* numbers, |
- int len) { |
- for (int i = 1; i < len; i++) { |
- int j = i; |
- while (j > 0 && |
- (NumberToUint32(numbers->get(j - 1)) > |
- NumberToUint32(numbers->get(j)))) { |
- content->SwapPairs(numbers, j - 1, j); |
- j--; |
- } |
- } |
-} |
- |
- |
-void HeapSortPairs(FixedArray* content, FixedArray* numbers, int len) { |
- // In-place heap sort. |
- DCHECK(content->length() == numbers->length()); |
- |
- // Bottom-up max-heap construction. |
- for (int i = 1; i < len; ++i) { |
- int child_index = i; |
- while (child_index > 0) { |
- int parent_index = ((child_index + 1) >> 1) - 1; |
- uint32_t parent_value = NumberToUint32(numbers->get(parent_index)); |
- uint32_t child_value = NumberToUint32(numbers->get(child_index)); |
- if (parent_value < child_value) { |
- content->SwapPairs(numbers, parent_index, child_index); |
- } else { |
- break; |
- } |
- child_index = parent_index; |
- } |
- } |
- |
- // Extract elements and create sorted array. |
- for (int i = len - 1; i > 0; --i) { |
- // Put max element at the back of the array. |
- content->SwapPairs(numbers, 0, i); |
- // Sift down the new top element. |
- int parent_index = 0; |
- while (true) { |
- int child_index = ((parent_index + 1) << 1) - 1; |
- if (child_index >= i) break; |
- uint32_t child1_value = NumberToUint32(numbers->get(child_index)); |
- uint32_t child2_value = NumberToUint32(numbers->get(child_index + 1)); |
- uint32_t parent_value = NumberToUint32(numbers->get(parent_index)); |
- if (child_index + 1 >= i || child1_value > child2_value) { |
- if (parent_value > child1_value) break; |
- content->SwapPairs(numbers, parent_index, child_index); |
- parent_index = child_index; |
- } else { |
- if (parent_value > child2_value) break; |
- content->SwapPairs(numbers, parent_index, child_index + 1); |
- parent_index = child_index + 1; |
- } |
- } |
- } |
-} |
- |
- |
-// Sort this array and the numbers as pairs wrt. the (distinct) numbers. |
-void FixedArray::SortPairs(FixedArray* numbers, uint32_t len) { |
- DCHECK(this->length() == numbers->length()); |
- // For small arrays, simply use insertion sort. |
- if (len <= 10) { |
- InsertionSortPairs(this, numbers, len); |
- return; |
- } |
- // Check the range of indices. |
- uint32_t min_index = NumberToUint32(numbers->get(0)); |
- uint32_t max_index = min_index; |
- uint32_t i; |
- for (i = 1; i < len; i++) { |
- if (NumberToUint32(numbers->get(i)) < min_index) { |
- min_index = NumberToUint32(numbers->get(i)); |
- } else if (NumberToUint32(numbers->get(i)) > max_index) { |
- max_index = NumberToUint32(numbers->get(i)); |
- } |
- } |
- if (max_index - min_index + 1 == len) { |
- // Indices form a contiguous range, unless there are duplicates. |
- // Do an in-place linear time sort assuming distinct numbers, but |
- // avoid hanging in case they are not. |
- for (i = 0; i < len; i++) { |
- uint32_t p; |
- uint32_t j = 0; |
- // While the current element at i is not at its correct position p, |
- // swap the elements at these two positions. |
- while ((p = NumberToUint32(numbers->get(i)) - min_index) != i && |
- j++ < len) { |
- SwapPairs(numbers, i, p); |
- } |
- } |
- } else { |
- HeapSortPairs(this, numbers, len); |
- return; |
- } |
-} |
- |
bool JSObject::WasConstructedFromApiFunction() { |
auto instance_type = map()->instance_type(); |
bool is_api_object = instance_type == JS_API_OBJECT_TYPE || |
@@ -17266,10 +17154,6 @@ Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>::Add( |
template Handle<FixedArray> Dictionary< |
NameDictionary, NameDictionaryShape, |
- Handle<Name> >::BuildIterationIndicesArray(Handle<NameDictionary>); |
- |
-template Handle<FixedArray> Dictionary< |
- NameDictionary, NameDictionaryShape, |
Handle<Name> >::GenerateNewEnumerationIndices(Handle<NameDictionary>); |
template Handle<SeededNumberDictionary> |
@@ -17324,6 +17208,12 @@ Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::CopyEnumKeysTo( |
Handle<FixedArray> storage, KeyCollectionMode mode, |
KeyAccumulator* accumulator); |
+template Handle<FixedArray> |
+Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>:: |
+ IterationIndices( |
+ Handle< |
+ Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>> |
+ dictionary); |
template void |
Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>:: |
CollectKeysTo(Handle<Dictionary<GlobalDictionary, GlobalDictionaryShape, |
@@ -17331,6 +17221,10 @@ Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>:: |
dictionary, |
KeyAccumulator* keys); |
+template Handle<FixedArray> |
+Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::IterationIndices( |
+ Handle<Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>> |
+ dictionary); |
template void |
Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::CollectKeysTo( |
Handle<Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>> |
@@ -18008,44 +17902,13 @@ Handle<Derived> Dictionary<Derived, Shape, Key>::New( |
return dict; |
} |
- |
-template <typename Derived, typename Shape, typename Key> |
-Handle<FixedArray> Dictionary<Derived, Shape, Key>::BuildIterationIndicesArray( |
- Handle<Derived> dictionary) { |
- Isolate* isolate = dictionary->GetIsolate(); |
- Factory* factory = isolate->factory(); |
- int length = dictionary->NumberOfElements(); |
- |
- Handle<FixedArray> iteration_order = factory->NewFixedArray(length); |
- Handle<FixedArray> enumeration_order = factory->NewFixedArray(length); |
- |
- // Fill both the iteration order array and the enumeration order array |
- // with property details. |
- int capacity = dictionary->Capacity(); |
- int pos = 0; |
- for (int i = 0; i < capacity; i++) { |
- if (dictionary->IsKey(isolate, dictionary->KeyAt(i))) { |
- int index = dictionary->DetailsAt(i).dictionary_index(); |
- iteration_order->set(pos, Smi::FromInt(i)); |
- enumeration_order->set(pos, Smi::FromInt(index)); |
- pos++; |
- } |
- } |
- DCHECK(pos == length); |
- |
- // Sort the arrays wrt. enumeration order. |
- iteration_order->SortPairs(*enumeration_order, enumeration_order->length()); |
- return iteration_order; |
-} |
- |
- |
template <typename Derived, typename Shape, typename Key> |
Handle<FixedArray> |
Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices( |
Handle<Derived> dictionary) { |
int length = dictionary->NumberOfElements(); |
- Handle<FixedArray> iteration_order = BuildIterationIndicesArray(dictionary); |
+ Handle<FixedArray> iteration_order = IterationIndices(dictionary); |
DCHECK(iteration_order->length() == length); |
// Iterate over the dictionary using the enumeration order and update |
@@ -18359,6 +18222,34 @@ void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo( |
} |
template <typename Derived, typename Shape, typename Key> |
+Handle<FixedArray> Dictionary<Derived, Shape, Key>::IterationIndices( |
+ Handle<Dictionary<Derived, Shape, Key>> dictionary) { |
+ Isolate* isolate = dictionary->GetIsolate(); |
+ int capacity = dictionary->Capacity(); |
+ int length = dictionary->NumberOfElements(); |
+ Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); |
+ int array_size = 0; |
+ { |
+ DisallowHeapAllocation no_gc; |
+ Dictionary<Derived, Shape, Key>* raw_dict = *dictionary; |
+ for (int i = 0; i < capacity; i++) { |
+ Object* k = raw_dict->KeyAt(i); |
+ if (!raw_dict->IsKey(isolate, k)) continue; |
+ if (raw_dict->IsDeleted(i)) continue; |
+ array->set(array_size++, Smi::FromInt(i)); |
+ } |
+ |
+ DCHECK_EQ(array_size, length); |
+ |
+ EnumIndexComparator<Derived> cmp(static_cast<Derived*>(raw_dict)); |
+ Smi** start = reinterpret_cast<Smi**>(array->GetFirstElementAddress()); |
+ std::sort(start, start + array_size, cmp); |
+ } |
+ array->Shrink(array_size); |
+ return array; |
+} |
+ |
+template <typename Derived, typename Shape, typename Key> |
void Dictionary<Derived, Shape, Key>::CollectKeysTo( |
Handle<Dictionary<Derived, Shape, Key>> dictionary, KeyAccumulator* keys) { |
Isolate* isolate = keys->isolate(); |