Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/value-serializer.cc

Issue 2304563004: Take advantage of fast properties in ValueSerializer when JSObject has them. (Closed)
Patch Set: cbruni review Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/value-serializer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/value-serializer.h" 5 #include "src/value-serializer.h"
6 6
7 #include <type_traits> 7 #include <type_traits>
8 8
9 #include "src/base/logging.h" 9 #include "src/base/logging.h"
10 #include "src/conversions.h" 10 #include "src/conversions.h"
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 case JS_DATA_VIEW_TYPE: 372 case JS_DATA_VIEW_TYPE:
373 return WriteJSArrayBufferView(JSArrayBufferView::cast(*receiver)); 373 return WriteJSArrayBufferView(JSArrayBufferView::cast(*receiver));
374 default: 374 default:
375 ThrowDataCloneError(MessageTemplate::kDataCloneError, receiver); 375 ThrowDataCloneError(MessageTemplate::kDataCloneError, receiver);
376 return Nothing<bool>(); 376 return Nothing<bool>();
377 } 377 }
378 return Nothing<bool>(); 378 return Nothing<bool>();
379 } 379 }
380 380
381 Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) { 381 Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) {
382 DCHECK_GT(object->map()->instance_type(), LAST_CUSTOM_ELEMENTS_RECEIVER);
383 const bool can_serialize_fast =
384 object->HasFastProperties() && object->elements()->length() == 0;
385 if (!can_serialize_fast) return WriteJSObjectSlow(object);
386
387 Handle<Map> map(object->map(), isolate_);
388 WriteTag(SerializationTag::kBeginJSObject);
389
390 // Write out fast properties as long as they are only data properties and the
391 // map doesn't change.
392 uint32_t properties_written = 0;
393 bool map_changed = false;
394 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
395 Handle<Name> key(map->instance_descriptors()->GetKey(i), isolate_);
396 if (!key->IsString()) continue;
397 PropertyDetails details = map->instance_descriptors()->GetDetails(i);
398 if (details.IsDontEnum()) continue;
399
400 Handle<Object> value;
401 if (V8_LIKELY(!map_changed)) map_changed = *map == object->map();
402 if (V8_LIKELY(!map_changed && details.type() == DATA)) {
403 FieldIndex field_index = FieldIndex::ForDescriptor(*map, i);
404 value = JSObject::FastPropertyAt(object, details.representation(),
405 field_index);
406 } else {
407 // This logic should essentially match WriteJSObjectPropertiesSlow.
408 // If the property is no longer found, do not serialize it.
409 // This could happen if a getter deleted the property.
410 LookupIterator it(isolate_, object, key, LookupIterator::OWN);
411 if (!it.IsFound()) continue;
412 if (!Object::GetProperty(&it).ToHandle(&value)) return Nothing<bool>();
413 }
414
415 if (!WriteObject(key).FromMaybe(false) ||
416 !WriteObject(value).FromMaybe(false)) {
417 return Nothing<bool>();
418 }
419 properties_written++;
420 }
421
422 WriteTag(SerializationTag::kEndJSObject);
423 WriteVarint<uint32_t>(properties_written);
424 return Just(true);
425 }
426
427 Maybe<bool> ValueSerializer::WriteJSObjectSlow(Handle<JSObject> object) {
382 WriteTag(SerializationTag::kBeginJSObject); 428 WriteTag(SerializationTag::kBeginJSObject);
383 Handle<FixedArray> keys; 429 Handle<FixedArray> keys;
384 uint32_t properties_written; 430 uint32_t properties_written;
385 if (!KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, 431 if (!KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly,
386 ENUMERABLE_STRINGS) 432 ENUMERABLE_STRINGS)
387 .ToHandle(&keys) || 433 .ToHandle(&keys) ||
388 !WriteJSObjectProperties(object, keys).To(&properties_written)) { 434 !WriteJSObjectPropertiesSlow(object, keys).To(&properties_written)) {
389 return Nothing<bool>(); 435 return Nothing<bool>();
390 } 436 }
391 WriteTag(SerializationTag::kEndJSObject); 437 WriteTag(SerializationTag::kEndJSObject);
392 WriteVarint<uint32_t>(properties_written); 438 WriteVarint<uint32_t>(properties_written);
393 return Just(true); 439 return Just(true);
394 } 440 }
395 441
396 Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) { 442 Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) {
397 uint32_t length = 0; 443 uint32_t length = 0;
398 bool valid_length = array->length()->ToArrayLength(&length); 444 bool valid_length = array->length()->ToArrayLength(&length);
(...skipping 26 matching lines...) Expand all
425 } 471 }
426 } 472 }
427 KeyAccumulator accumulator(isolate_, KeyCollectionMode::kOwnOnly, 473 KeyAccumulator accumulator(isolate_, KeyCollectionMode::kOwnOnly,
428 ENUMERABLE_STRINGS); 474 ENUMERABLE_STRINGS);
429 if (!accumulator.CollectOwnPropertyNames(array, array).FromMaybe(false)) { 475 if (!accumulator.CollectOwnPropertyNames(array, array).FromMaybe(false)) {
430 return Nothing<bool>(); 476 return Nothing<bool>();
431 } 477 }
432 Handle<FixedArray> keys = 478 Handle<FixedArray> keys =
433 accumulator.GetKeys(GetKeysConversion::kConvertToString); 479 accumulator.GetKeys(GetKeysConversion::kConvertToString);
434 uint32_t properties_written; 480 uint32_t properties_written;
435 if (!WriteJSObjectProperties(array, keys).To(&properties_written)) { 481 if (!WriteJSObjectPropertiesSlow(array, keys).To(&properties_written)) {
436 return Nothing<bool>(); 482 return Nothing<bool>();
437 } 483 }
438 WriteTag(SerializationTag::kEndDenseJSArray); 484 WriteTag(SerializationTag::kEndDenseJSArray);
439 WriteVarint<uint32_t>(properties_written); 485 WriteVarint<uint32_t>(properties_written);
440 WriteVarint<uint32_t>(length); 486 WriteVarint<uint32_t>(length);
441 } else { 487 } else {
442 WriteTag(SerializationTag::kBeginSparseJSArray); 488 WriteTag(SerializationTag::kBeginSparseJSArray);
443 WriteVarint<uint32_t>(length); 489 WriteVarint<uint32_t>(length);
444 Handle<FixedArray> keys; 490 Handle<FixedArray> keys;
445 uint32_t properties_written; 491 uint32_t properties_written;
446 if (!KeyAccumulator::GetKeys(array, KeyCollectionMode::kOwnOnly, 492 if (!KeyAccumulator::GetKeys(array, KeyCollectionMode::kOwnOnly,
447 ENUMERABLE_STRINGS) 493 ENUMERABLE_STRINGS)
448 .ToHandle(&keys) || 494 .ToHandle(&keys) ||
449 !WriteJSObjectProperties(array, keys).To(&properties_written)) { 495 !WriteJSObjectPropertiesSlow(array, keys).To(&properties_written)) {
450 return Nothing<bool>(); 496 return Nothing<bool>();
451 } 497 }
452 WriteTag(SerializationTag::kEndSparseJSArray); 498 WriteTag(SerializationTag::kEndSparseJSArray);
453 WriteVarint<uint32_t>(properties_written); 499 WriteVarint<uint32_t>(properties_written);
454 WriteVarint<uint32_t>(length); 500 WriteVarint<uint32_t>(length);
455 } 501 }
456 return Just(true); 502 return Just(true);
457 } 503 }
458 504
459 void ValueSerializer::WriteJSDate(JSDate* date) { 505 void ValueSerializer::WriteJSDate(JSDate* date) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 } else { 653 } else {
608 DCHECK(view->IsJSDataView()); 654 DCHECK(view->IsJSDataView());
609 tag = ArrayBufferViewTag::kDataView; 655 tag = ArrayBufferViewTag::kDataView;
610 } 656 }
611 WriteVarint(static_cast<uint8_t>(tag)); 657 WriteVarint(static_cast<uint8_t>(tag));
612 WriteVarint(NumberToUint32(view->byte_offset())); 658 WriteVarint(NumberToUint32(view->byte_offset()));
613 WriteVarint(NumberToUint32(view->byte_length())); 659 WriteVarint(NumberToUint32(view->byte_length()));
614 return Just(true); 660 return Just(true);
615 } 661 }
616 662
617 Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties( 663 Maybe<uint32_t> ValueSerializer::WriteJSObjectPropertiesSlow(
618 Handle<JSObject> object, Handle<FixedArray> keys) { 664 Handle<JSObject> object, Handle<FixedArray> keys) {
619 uint32_t properties_written = 0; 665 uint32_t properties_written = 0;
620 int length = keys->length(); 666 int length = keys->length();
621 for (int i = 0; i < length; i++) { 667 for (int i = 0; i < length; i++) {
622 Handle<Object> key(keys->get(i), isolate_); 668 Handle<Object> key(keys->get(i), isolate_);
623 669
624 bool success; 670 bool success;
625 LookupIterator it = LookupIterator::PropertyOrElement( 671 LookupIterator it = LookupIterator::PropertyOrElement(
626 isolate_, object, key, &success, LookupIterator::OWN); 672 isolate_, object, key, &success, LookupIterator::OWN);
627 DCHECK(success); 673 DCHECK(success);
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
1393 if (stack.size() != 1) { 1439 if (stack.size() != 1) {
1394 isolate_->Throw(*isolate_->factory()->NewError( 1440 isolate_->Throw(*isolate_->factory()->NewError(
1395 MessageTemplate::kDataCloneDeserializationError)); 1441 MessageTemplate::kDataCloneDeserializationError));
1396 return MaybeHandle<Object>(); 1442 return MaybeHandle<Object>();
1397 } 1443 }
1398 return scope.CloseAndEscape(stack[0]); 1444 return scope.CloseAndEscape(stack[0]);
1399 } 1445 }
1400 1446
1401 } // namespace internal 1447 } // namespace internal
1402 } // namespace v8 1448 } // namespace v8
OLDNEW
« no previous file with comments | « src/value-serializer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698