Chromium Code Reviews| Index: src/value-serializer.cc |
| diff --git a/src/value-serializer.cc b/src/value-serializer.cc |
| index 8416ea3cd61dea9ad11ba148f83339153b4e4f4a..a11e5d954dd6f385e3a2917c8ade33590091d777 100644 |
| --- a/src/value-serializer.cc |
| +++ b/src/value-serializer.cc |
| @@ -375,13 +375,60 @@ 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); |
| + |
| + DCHECK(!object->IsJSGlobalProxy()); |
| + DCHECK(!object->HasIndexedInterceptor()); |
| + DCHECK(!object->HasNamedInterceptor()); |
|
Camillo Bruni
2016/09/05 16:49:41
nit: you can replace the DCHECKS above with DCHECK
jbroman
2016/09/06 17:37:50
Removed, then. Such a check already occurs at the
|
| + 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; |
| + 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(details.type() == DATA && *map == object->map())) { |
|
Camillo Bruni
2016/09/05 16:49:41
performance-nit: you may want to use a bool stable
jbroman
2016/09/06 17:37:50
OK, done. (As above, I was matching json-stringifi
|
| + 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); |
| @@ -428,7 +475,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); |
| @@ -442,7 +489,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); |
| @@ -601,7 +648,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(); |