| Index: src/value-serializer.cc
|
| diff --git a/src/value-serializer.cc b/src/value-serializer.cc
|
| index c20711d8a24fbd82169759077c259fd296bb6d9b..56d8fa5d059602ed39496a138e237b709cfd602a 100644
|
| --- a/src/value-serializer.cc
|
| +++ b/src/value-serializer.cc
|
| @@ -379,13 +379,59 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) {
|
| }
|
|
|
| Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) {
|
| + DCHECK_GT(object->map()->instance_type(), LAST_CUSTOM_ELEMENTS_RECEIVER);
|
| + const bool can_serialize_fast =
|
| + object->HasFastProperties() && object->elements()->length() == 0;
|
| + if (!can_serialize_fast) return WriteJSObjectSlow(object);
|
| +
|
| + Handle<Map> map(object->map(), isolate_);
|
| + WriteTag(SerializationTag::kBeginJSObject);
|
| +
|
| + // Write out fast properties as long as they are only data properties and the
|
| + // map doesn't change.
|
| + uint32_t properties_written = 0;
|
| + bool map_changed = false;
|
| + for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
|
| + Handle<Name> key(map->instance_descriptors()->GetKey(i), isolate_);
|
| + if (!key->IsString()) continue;
|
| + PropertyDetails details = map->instance_descriptors()->GetDetails(i);
|
| + if (details.IsDontEnum()) continue;
|
| +
|
| + Handle<Object> value;
|
| + if (V8_LIKELY(!map_changed)) map_changed = *map == object->map();
|
| + if (V8_LIKELY(!map_changed && details.type() == DATA)) {
|
| + FieldIndex field_index = FieldIndex::ForDescriptor(*map, i);
|
| + value = JSObject::FastPropertyAt(object, details.representation(),
|
| + field_index);
|
| + } else {
|
| + // This logic should essentially match WriteJSObjectPropertiesSlow.
|
| + // If the property is no longer found, do not serialize it.
|
| + // This could happen if a getter deleted the property.
|
| + LookupIterator it(isolate_, object, key, LookupIterator::OWN);
|
| + if (!it.IsFound()) continue;
|
| + if (!Object::GetProperty(&it).ToHandle(&value)) return Nothing<bool>();
|
| + }
|
| +
|
| + if (!WriteObject(key).FromMaybe(false) ||
|
| + !WriteObject(value).FromMaybe(false)) {
|
| + return Nothing<bool>();
|
| + }
|
| + properties_written++;
|
| + }
|
| +
|
| + WriteTag(SerializationTag::kEndJSObject);
|
| + WriteVarint<uint32_t>(properties_written);
|
| + return Just(true);
|
| +}
|
| +
|
| +Maybe<bool> ValueSerializer::WriteJSObjectSlow(Handle<JSObject> object) {
|
| WriteTag(SerializationTag::kBeginJSObject);
|
| Handle<FixedArray> keys;
|
| uint32_t properties_written;
|
| if (!KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly,
|
| ENUMERABLE_STRINGS)
|
| .ToHandle(&keys) ||
|
| - !WriteJSObjectProperties(object, keys).To(&properties_written)) {
|
| + !WriteJSObjectPropertiesSlow(object, keys).To(&properties_written)) {
|
| return Nothing<bool>();
|
| }
|
| WriteTag(SerializationTag::kEndJSObject);
|
| @@ -432,7 +478,7 @@ Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) {
|
| Handle<FixedArray> keys =
|
| accumulator.GetKeys(GetKeysConversion::kConvertToString);
|
| uint32_t properties_written;
|
| - if (!WriteJSObjectProperties(array, keys).To(&properties_written)) {
|
| + if (!WriteJSObjectPropertiesSlow(array, keys).To(&properties_written)) {
|
| return Nothing<bool>();
|
| }
|
| WriteTag(SerializationTag::kEndDenseJSArray);
|
| @@ -446,7 +492,7 @@ Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) {
|
| if (!KeyAccumulator::GetKeys(array, KeyCollectionMode::kOwnOnly,
|
| ENUMERABLE_STRINGS)
|
| .ToHandle(&keys) ||
|
| - !WriteJSObjectProperties(array, keys).To(&properties_written)) {
|
| + !WriteJSObjectPropertiesSlow(array, keys).To(&properties_written)) {
|
| return Nothing<bool>();
|
| }
|
| WriteTag(SerializationTag::kEndSparseJSArray);
|
| @@ -614,7 +660,7 @@ Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView* view) {
|
| return Just(true);
|
| }
|
|
|
| -Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties(
|
| +Maybe<uint32_t> ValueSerializer::WriteJSObjectPropertiesSlow(
|
| Handle<JSObject> object, Handle<FixedArray> keys) {
|
| uint32_t properties_written = 0;
|
| int length = keys->length();
|
|
|