Commit cda9a799 authored by cbruni's avatar cbruni Committed by Commit bot

[elements] Fix sorting dictionary element keys

Using std::sort on a FixedArray with HeapNumbers is not very GC friendly.
Adding a separate step to properly record possible HeapNumbers.

BUG=chromium:594954
LOG=N

Review URL: https://codereview.chromium.org/1807173002

Cr-Commit-Position: refs/heads/master@{#34888}
parent 8ba35e73
......@@ -722,11 +722,11 @@ class ElementsAccessorBase : public ElementsAccessor {
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());
} else {
return ElementsAccessorSubclass::GetCapacityImpl(receiver, elements);
}
return ElementsAccessorSubclass::GetCapacityImpl(receiver, elements);
}
static Handle<FixedArrayBase> ConvertElementsWithCapacity(
......@@ -946,6 +946,7 @@ class ElementsAccessorBase : public ElementsAccessor {
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.
if (convert == CONVERT_TO_STRING) {
......@@ -954,6 +955,18 @@ class ElementsAccessorBase : public ElementsAccessor {
combined_keys->get(i)->Number());
combined_keys->set(i, *index_string);
}
} else if (!(object->IsJSArray() &&
JSArray::cast(*object)->length()->ToArrayLength(
&array_length) &&
array_length <= Smi::kMaxValue)) {
// Since we use std::sort above, the GC will no longer know where the
// HeapNumbers are, hence we have to write them again.
// For Arrays with valid Smi length, we are sure to have no HeapNumber
// indices and thus we can skip this step.
for (uint32_t i = 0; i < nof_indices; i++) {
Object* index = combined_keys->get(i);
combined_keys->set(i, index);
}
}
}
......@@ -1039,6 +1052,19 @@ class DictionaryElementsAccessor
: ElementsAccessorBase<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;
}
static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array,
uint32_t length,
Handle<FixedArrayBase> backing_store) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment