This backport fixes a performance pathology in how arrays grow/shrink.
Fixes: https://github.com/nodejs/node/issues/3538
V8-Commit: https://github.com/v8/v8/commit/
066747ea053012a99e0cd3e20f36b8ed053b2124
PR-URL: https://github.com/nodejs/node/pull/4625
Reviewed-By: cjihrig - Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: targos - Michaël Zasso <mic.besace@gmail.com>
Reviewed-By: indutny - Fedor Indutny <fedor.indutny@gmail.com>
Original commit message:
Make sure that NormalizeElements and ShouldConvertToFastElements are …
…based on the same values
BUG=v8:4518
LOG=n
Review URL: https://codereview.chromium.org/
1472293002
Cr-Commit-Position: refs/heads/master@{#32265}
Commit metadata for v4.x-staging:
PR-URL: https://github.com/nodejs/node/pull/4655
Reviewed-By: James M Snell <jasnell@gmail.com>
}
int num_used = 0;
for (int i = 0; i < backing_store->length(); ++i) {
- if (!backing_store->is_the_hole(i)) ++num_used;
- // Bail out early if more than 1/4 is used.
- if (4 * num_used > backing_store->length()) break;
- }
- if (4 * num_used <= backing_store->length()) {
- JSObject::NormalizeElements(obj);
+ if (!backing_store->is_the_hole(i)) {
+ ++num_used;
+ // Bail out if a number dictionary wouldn't be able to save at least
+ // 75% space.
+ if (4 * SeededNumberDictionary::ComputeCapacity(num_used) *
+ SeededNumberDictionary::kEntrySize >
+ backing_store->length()) {
+ return;
+ }
+ }
}
+ JSObject::NormalizeElements(obj);
}
}
uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
SeededNumberDictionary::kEntrySize;
+
+ // Turn fast if the dictionary only saves 50% space.
return 2 * dictionary_size >= *new_capacity;
}