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

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 comments 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 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 case JS_DATA_VIEW_TYPE: 368 case JS_DATA_VIEW_TYPE:
369 return WriteJSArrayBufferView(JSArrayBufferView::cast(*receiver)); 369 return WriteJSArrayBufferView(JSArrayBufferView::cast(*receiver));
370 default: 370 default:
371 UNIMPLEMENTED(); 371 UNIMPLEMENTED();
372 break; 372 break;
373 } 373 }
374 return Nothing<bool>(); 374 return Nothing<bool>();
375 } 375 }
376 376
377 Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) { 377 Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) {
378 DCHECK_GT(object->map()->instance_type(), LAST_CUSTOM_ELEMENTS_RECEIVER);
379 const bool can_serialize_fast =
380 object->HasFastProperties() && object->elements()->length() == 0;
381 if (!can_serialize_fast) return WriteJSObjectSlow(object);
382
383 DCHECK(!object->IsJSGlobalProxy());
384 DCHECK(!object->HasIndexedInterceptor());
385 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
386 Handle<Map> map(object->map(), isolate_);
387 WriteTag(SerializationTag::kBeginJSObject);
388
389 // Write out fast properties as long as they are only data properties and the
390 // map doesn't change.
391 uint32_t properties_written = 0;
392 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
393 Handle<Name> key(map->instance_descriptors()->GetKey(i), isolate_);
394 if (!key->IsString()) continue;
395 PropertyDetails details = map->instance_descriptors()->GetDetails(i);
396 if (details.IsDontEnum()) continue;
397
398 Handle<Object> value;
399 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
400 FieldIndex field_index = FieldIndex::ForDescriptor(*map, i);
401 value = JSObject::FastPropertyAt(object, details.representation(),
402 field_index);
403 } else {
404 // This logic should essentially match WriteJSObjectPropertiesSlow.
405 // If the property is no longer found, do not serialize it.
406 // This could happen if a getter deleted the property.
407 LookupIterator it(isolate_, object, key, LookupIterator::OWN);
408 if (!it.IsFound()) continue;
409 if (!Object::GetProperty(&it).ToHandle(&value)) return Nothing<bool>();
410 }
411
412 if (!WriteObject(key).FromMaybe(false) ||
413 !WriteObject(value).FromMaybe(false)) {
414 return Nothing<bool>();
415 }
416 properties_written++;
417 }
418
419 WriteTag(SerializationTag::kEndJSObject);
420 WriteVarint<uint32_t>(properties_written);
421 return Just(true);
422 }
423
424 Maybe<bool> ValueSerializer::WriteJSObjectSlow(Handle<JSObject> object) {
378 WriteTag(SerializationTag::kBeginJSObject); 425 WriteTag(SerializationTag::kBeginJSObject);
379 Handle<FixedArray> keys; 426 Handle<FixedArray> keys;
380 uint32_t properties_written; 427 uint32_t properties_written;
381 if (!KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, 428 if (!KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly,
382 ENUMERABLE_STRINGS) 429 ENUMERABLE_STRINGS)
383 .ToHandle(&keys) || 430 .ToHandle(&keys) ||
384 !WriteJSObjectProperties(object, keys).To(&properties_written)) { 431 !WriteJSObjectPropertiesSlow(object, keys).To(&properties_written)) {
385 return Nothing<bool>(); 432 return Nothing<bool>();
386 } 433 }
387 WriteTag(SerializationTag::kEndJSObject); 434 WriteTag(SerializationTag::kEndJSObject);
388 WriteVarint<uint32_t>(properties_written); 435 WriteVarint<uint32_t>(properties_written);
389 return Just(true); 436 return Just(true);
390 } 437 }
391 438
392 Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) { 439 Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) {
393 uint32_t length = 0; 440 uint32_t length = 0;
394 bool valid_length = array->length()->ToArrayLength(&length); 441 bool valid_length = array->length()->ToArrayLength(&length);
(...skipping 26 matching lines...) Expand all
421 } 468 }
422 } 469 }
423 KeyAccumulator accumulator(isolate_, KeyCollectionMode::kOwnOnly, 470 KeyAccumulator accumulator(isolate_, KeyCollectionMode::kOwnOnly,
424 ENUMERABLE_STRINGS); 471 ENUMERABLE_STRINGS);
425 if (!accumulator.CollectOwnPropertyNames(array, array).FromMaybe(false)) { 472 if (!accumulator.CollectOwnPropertyNames(array, array).FromMaybe(false)) {
426 return Nothing<bool>(); 473 return Nothing<bool>();
427 } 474 }
428 Handle<FixedArray> keys = 475 Handle<FixedArray> keys =
429 accumulator.GetKeys(GetKeysConversion::kConvertToString); 476 accumulator.GetKeys(GetKeysConversion::kConvertToString);
430 uint32_t properties_written; 477 uint32_t properties_written;
431 if (!WriteJSObjectProperties(array, keys).To(&properties_written)) { 478 if (!WriteJSObjectPropertiesSlow(array, keys).To(&properties_written)) {
432 return Nothing<bool>(); 479 return Nothing<bool>();
433 } 480 }
434 WriteTag(SerializationTag::kEndDenseJSArray); 481 WriteTag(SerializationTag::kEndDenseJSArray);
435 WriteVarint<uint32_t>(properties_written); 482 WriteVarint<uint32_t>(properties_written);
436 WriteVarint<uint32_t>(length); 483 WriteVarint<uint32_t>(length);
437 } else { 484 } else {
438 WriteTag(SerializationTag::kBeginSparseJSArray); 485 WriteTag(SerializationTag::kBeginSparseJSArray);
439 WriteVarint<uint32_t>(length); 486 WriteVarint<uint32_t>(length);
440 Handle<FixedArray> keys; 487 Handle<FixedArray> keys;
441 uint32_t properties_written; 488 uint32_t properties_written;
442 if (!KeyAccumulator::GetKeys(array, KeyCollectionMode::kOwnOnly, 489 if (!KeyAccumulator::GetKeys(array, KeyCollectionMode::kOwnOnly,
443 ENUMERABLE_STRINGS) 490 ENUMERABLE_STRINGS)
444 .ToHandle(&keys) || 491 .ToHandle(&keys) ||
445 !WriteJSObjectProperties(array, keys).To(&properties_written)) { 492 !WriteJSObjectPropertiesSlow(array, keys).To(&properties_written)) {
446 return Nothing<bool>(); 493 return Nothing<bool>();
447 } 494 }
448 WriteTag(SerializationTag::kEndSparseJSArray); 495 WriteTag(SerializationTag::kEndSparseJSArray);
449 WriteVarint<uint32_t>(properties_written); 496 WriteVarint<uint32_t>(properties_written);
450 WriteVarint<uint32_t>(length); 497 WriteVarint<uint32_t>(length);
451 } 498 }
452 return Just(true); 499 return Just(true);
453 } 500 }
454 501
455 void ValueSerializer::WriteJSDate(JSDate* date) { 502 void ValueSerializer::WriteJSDate(JSDate* date) {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 } else { 641 } else {
595 DCHECK(view->IsJSDataView()); 642 DCHECK(view->IsJSDataView());
596 tag = ArrayBufferViewTag::kDataView; 643 tag = ArrayBufferViewTag::kDataView;
597 } 644 }
598 WriteVarint(static_cast<uint8_t>(tag)); 645 WriteVarint(static_cast<uint8_t>(tag));
599 WriteVarint(NumberToUint32(view->byte_offset())); 646 WriteVarint(NumberToUint32(view->byte_offset()));
600 WriteVarint(NumberToUint32(view->byte_length())); 647 WriteVarint(NumberToUint32(view->byte_length()));
601 return Just(true); 648 return Just(true);
602 } 649 }
603 650
604 Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties( 651 Maybe<uint32_t> ValueSerializer::WriteJSObjectPropertiesSlow(
605 Handle<JSObject> object, Handle<FixedArray> keys) { 652 Handle<JSObject> object, Handle<FixedArray> keys) {
606 uint32_t properties_written = 0; 653 uint32_t properties_written = 0;
607 int length = keys->length(); 654 int length = keys->length();
608 for (int i = 0; i < length; i++) { 655 for (int i = 0; i < length; i++) {
609 Handle<Object> key(keys->get(i), isolate_); 656 Handle<Object> key(keys->get(i), isolate_);
610 657
611 bool success; 658 bool success;
612 LookupIterator it = LookupIterator::PropertyOrElement( 659 LookupIterator it = LookupIterator::PropertyOrElement(
613 isolate_, object, key, &success, LookupIterator::OWN); 660 isolate_, object, key, &success, LookupIterator::OWN);
614 DCHECK(success); 661 DCHECK(success);
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 } 1395 }
1349 #endif 1396 #endif
1350 position_ = end_; 1397 position_ = end_;
1351 1398
1352 if (stack.size() != 1) return MaybeHandle<Object>(); 1399 if (stack.size() != 1) return MaybeHandle<Object>();
1353 return scope.CloseAndEscape(stack[0]); 1400 return scope.CloseAndEscape(stack[0]);
1354 } 1401 }
1355 1402
1356 } // namespace internal 1403 } // namespace internal
1357 } // namespace v8 1404 } // 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