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

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

Issue 2304563004: Take advantage of fast properties in ValueSerializer when JSObject has them. (Closed)
Patch Set: 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(object->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER);
Camillo Bruni 2016/09/01 20:50:32 nit: Use DCHECK_GT(left..., right..)
jbroman 2016/09/02 15:31:42 Done.
379 const bool can_serialize_fast =
380 object->HasFastProperties() && object->elements()->length() == 0;
Camillo Bruni 2016/09/01 20:50:32 I guess this is WIP, elements() can be easily seri
Jakob Kummerow 2016/09/02 10:44:23 It's not that easy. Any element that's an object i
jbroman 2016/09/02 15:31:42 +1. And this matches what json-stringifier does (w
381 if (!can_serialize_fast) return WriteJSObjectSlow(object);
382
383 DCHECK(!object->IsJSGlobalProxy());
384 DCHECK(!object->HasIndexedInterceptor());
385 DCHECK(!object->HasNamedInterceptor());
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())) {
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 bool success;
406 LookupIterator it = LookupIterator::PropertyOrElement(
407 isolate_, object, key, &success, LookupIterator::OWN);
Camillo Bruni 2016/09/01 20:50:32 You can bypass the arrayIndex check in PropertyOrE
jbroman 2016/09/02 15:31:42 Done.
408 DCHECK(success);
409 if (!Object::GetProperty(&it).ToHandle(&value)) return Nothing<bool>();
410
411 // If the property is no longer found, do not serialize it.
412 // This could happen if a getter deleted the property.
413 if (!it.IsFound()) continue;
Camillo Bruni 2016/09/01 20:50:32 You can push the IsFound() check above the GetProp
jbroman 2016/09/02 15:31:42 Done.
414 }
415
416 if (!WriteObject(key).FromMaybe(false) ||
417 !WriteObject(value).FromMaybe(false)) {
418 return Nothing<bool>();
419 }
420 properties_written++;
421 }
422
423 WriteTag(SerializationTag::kEndJSObject);
424 WriteVarint<uint32_t>(properties_written);
425 return Just(true);
426 }
427
428 Maybe<bool> ValueSerializer::WriteJSObjectSlow(Handle<JSObject> object) {
378 WriteTag(SerializationTag::kBeginJSObject); 429 WriteTag(SerializationTag::kBeginJSObject);
379 Handle<FixedArray> keys; 430 Handle<FixedArray> keys;
380 uint32_t properties_written; 431 uint32_t properties_written;
381 if (!KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, 432 if (!KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly,
382 ENUMERABLE_STRINGS) 433 ENUMERABLE_STRINGS)
383 .ToHandle(&keys) || 434 .ToHandle(&keys) ||
384 !WriteJSObjectProperties(object, keys).To(&properties_written)) { 435 !WriteJSObjectPropertiesSlow(object, keys).To(&properties_written)) {
385 return Nothing<bool>(); 436 return Nothing<bool>();
386 } 437 }
387 WriteTag(SerializationTag::kEndJSObject); 438 WriteTag(SerializationTag::kEndJSObject);
388 WriteVarint<uint32_t>(properties_written); 439 WriteVarint<uint32_t>(properties_written);
389 return Just(true); 440 return Just(true);
390 } 441 }
391 442
392 Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) { 443 Maybe<bool> ValueSerializer::WriteJSArray(Handle<JSArray> array) {
393 uint32_t length = 0; 444 uint32_t length = 0;
394 bool valid_length = array->length()->ToArrayLength(&length); 445 bool valid_length = array->length()->ToArrayLength(&length);
(...skipping 26 matching lines...) Expand all
421 } 472 }
422 } 473 }
423 KeyAccumulator accumulator(isolate_, KeyCollectionMode::kOwnOnly, 474 KeyAccumulator accumulator(isolate_, KeyCollectionMode::kOwnOnly,
424 ENUMERABLE_STRINGS); 475 ENUMERABLE_STRINGS);
425 if (!accumulator.CollectOwnPropertyNames(array, array).FromMaybe(false)) { 476 if (!accumulator.CollectOwnPropertyNames(array, array).FromMaybe(false)) {
426 return Nothing<bool>(); 477 return Nothing<bool>();
427 } 478 }
428 Handle<FixedArray> keys = 479 Handle<FixedArray> keys =
429 accumulator.GetKeys(GetKeysConversion::kConvertToString); 480 accumulator.GetKeys(GetKeysConversion::kConvertToString);
430 uint32_t properties_written; 481 uint32_t properties_written;
431 if (!WriteJSObjectProperties(array, keys).To(&properties_written)) { 482 if (!WriteJSObjectPropertiesSlow(array, keys).To(&properties_written)) {
432 return Nothing<bool>(); 483 return Nothing<bool>();
433 } 484 }
434 WriteTag(SerializationTag::kEndDenseJSArray); 485 WriteTag(SerializationTag::kEndDenseJSArray);
435 WriteVarint<uint32_t>(properties_written); 486 WriteVarint<uint32_t>(properties_written);
436 WriteVarint<uint32_t>(length); 487 WriteVarint<uint32_t>(length);
437 } else { 488 } else {
438 WriteTag(SerializationTag::kBeginSparseJSArray); 489 WriteTag(SerializationTag::kBeginSparseJSArray);
439 WriteVarint<uint32_t>(length); 490 WriteVarint<uint32_t>(length);
440 Handle<FixedArray> keys; 491 Handle<FixedArray> keys;
441 uint32_t properties_written; 492 uint32_t properties_written;
442 if (!KeyAccumulator::GetKeys(array, KeyCollectionMode::kOwnOnly, 493 if (!KeyAccumulator::GetKeys(array, KeyCollectionMode::kOwnOnly,
443 ENUMERABLE_STRINGS) 494 ENUMERABLE_STRINGS)
444 .ToHandle(&keys) || 495 .ToHandle(&keys) ||
445 !WriteJSObjectProperties(array, keys).To(&properties_written)) { 496 !WriteJSObjectPropertiesSlow(array, keys).To(&properties_written)) {
446 return Nothing<bool>(); 497 return Nothing<bool>();
447 } 498 }
448 WriteTag(SerializationTag::kEndSparseJSArray); 499 WriteTag(SerializationTag::kEndSparseJSArray);
449 WriteVarint<uint32_t>(properties_written); 500 WriteVarint<uint32_t>(properties_written);
450 WriteVarint<uint32_t>(length); 501 WriteVarint<uint32_t>(length);
451 } 502 }
452 return Just(true); 503 return Just(true);
453 } 504 }
454 505
455 void ValueSerializer::WriteJSDate(JSDate* date) { 506 void ValueSerializer::WriteJSDate(JSDate* date) {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 } else { 645 } else {
595 DCHECK(view->IsJSDataView()); 646 DCHECK(view->IsJSDataView());
596 tag = ArrayBufferViewTag::kDataView; 647 tag = ArrayBufferViewTag::kDataView;
597 } 648 }
598 WriteVarint(static_cast<uint8_t>(tag)); 649 WriteVarint(static_cast<uint8_t>(tag));
599 WriteVarint(NumberToUint32(view->byte_offset())); 650 WriteVarint(NumberToUint32(view->byte_offset()));
600 WriteVarint(NumberToUint32(view->byte_length())); 651 WriteVarint(NumberToUint32(view->byte_length()));
601 return Just(true); 652 return Just(true);
602 } 653 }
603 654
604 Maybe<uint32_t> ValueSerializer::WriteJSObjectProperties( 655 Maybe<uint32_t> ValueSerializer::WriteJSObjectPropertiesSlow(
605 Handle<JSObject> object, Handle<FixedArray> keys) { 656 Handle<JSObject> object, Handle<FixedArray> keys) {
606 uint32_t properties_written = 0; 657 uint32_t properties_written = 0;
607 int length = keys->length(); 658 int length = keys->length();
608 for (int i = 0; i < length; i++) { 659 for (int i = 0; i < length; i++) {
609 Handle<Object> key(keys->get(i), isolate_); 660 Handle<Object> key(keys->get(i), isolate_);
610 661
611 bool success; 662 bool success;
612 LookupIterator it = LookupIterator::PropertyOrElement( 663 LookupIterator it = LookupIterator::PropertyOrElement(
613 isolate_, object, key, &success, LookupIterator::OWN); 664 isolate_, object, key, &success, LookupIterator::OWN);
614 DCHECK(success); 665 DCHECK(success);
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 } 1399 }
1349 #endif 1400 #endif
1350 position_ = end_; 1401 position_ = end_;
1351 1402
1352 if (stack.size() != 1) return MaybeHandle<Object>(); 1403 if (stack.size() != 1) return MaybeHandle<Object>();
1353 return scope.CloseAndEscape(stack[0]); 1404 return scope.CloseAndEscape(stack[0]);
1354 } 1405 }
1355 1406
1356 } // namespace internal 1407 } // namespace internal
1357 } // namespace v8 1408 } // 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