[runtime] Add Normalization step in SetOrCopyDataProperties

Normalize the target object if we're guaranteed to end up in
dicionary mode after copying over all enumerable properties from the
source object.

This partially addresses performance issues when using the spread
operator on large dict-mode objects.

Change-Id: I5be7cbc6e6a7e4b1b59412779db9b651f5f68b45
Bug: v8:10763
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2362961
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69713}
This commit is contained in:
Camillo Bruni 2020-08-19 17:17:24 +02:00 committed by Commit Bot
parent 37ccb46b2a
commit 0017c7bb86

View File

@ -309,6 +309,7 @@ Maybe<bool> JSReceiver::SetOrCopyDataProperties(
if (fast_assign.FromJust()) return Just(true);
Handle<JSReceiver> from = Object::ToObject(isolate, source).ToHandleChecked();
// 3b. Let keys be ? from.[[OwnPropertyKeys]]().
Handle<FixedArray> keys;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
@ -317,9 +318,21 @@ Maybe<bool> JSReceiver::SetOrCopyDataProperties(
GetKeysConversion::kKeepNumbers),
Nothing<bool>());
if (!from->HasFastProperties() && target->HasFastProperties()) {
// Convert to slow properties if we're guaranteed to overflow the number of
// descriptors.
int source_length =
from->property_dictionary().NumberOfEnumerableProperties();
if (source_length > kMaxNumberOfDescriptors) {
JSObject::NormalizeProperties(isolate, Handle<JSObject>::cast(target),
CLEAR_INOBJECT_PROPERTIES, source_length,
"Copying data properties");
}
}
// 4. Repeat for each element nextKey of keys in List order,
for (int j = 0; j < keys->length(); ++j) {
Handle<Object> next_key(keys->get(j), isolate);
for (int i = 0; i < keys->length(); ++i) {
Handle<Object> next_key(keys->get(i), isolate);
// 4a i. Let desc be ? from.[[GetOwnProperty]](nextKey).
PropertyDescriptor desc;
Maybe<bool> found =