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

Side by Side Diff: src/snapshot/serializer.cc

Issue 2799943002: Handle ExternalStrings directly in the serializer without ObjectVisitor. (Closed)
Patch Set: Created 3 years, 8 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/snapshot/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/snapshot/serializer.h" 5 #include "src/snapshot/serializer.h"
6 6
7 #include "src/assembler-inl.h" 7 #include "src/assembler-inl.h"
8 #include "src/deoptimizer.h" 8 #include "src/deoptimizer.h"
9 #include "src/heap/heap-inl.h" 9 #include "src/heap/heap-inl.h"
10 #include "src/macro-assembler.h" 10 #include "src/macro-assembler.h"
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 #endif // OBJECT_PRINT 394 #endif // OBJECT_PRINT
395 395
396 // Mark this object as already serialized. 396 // Mark this object as already serialized.
397 serializer_->reference_map()->Add(object_, back_reference); 397 serializer_->reference_map()->Add(object_, back_reference);
398 398
399 // Serialize the map (first word of the object). 399 // Serialize the map (first word of the object).
400 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0); 400 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0);
401 } 401 }
402 402
403 void Serializer::ObjectSerializer::SerializeExternalString() { 403 void Serializer::ObjectSerializer::SerializeExternalString() {
404 Heap* heap = serializer_->isolate()->heap();
405 if (object_->map() != heap->native_source_string_map()) {
406 // Usually we cannot recreate resources for external strings. To work
407 // around this, external strings are serialized to look like ordinary
408 // sequential strings.
409 // The exception are native source code strings, since we can recreate
410 // their resources.
411 SerializeExternalStringAsSequentialString();
412 } else {
413 DCHECK(object_->IsExternalOneByteString());
414 DCHECK(ExternalOneByteString::cast(object_)->is_short());
415 int size = object_->Size();
416 Map* map = object_->map();
417 AllocationSpace space =
418 MemoryChunk::FromAddress(object_->address())->owner()->identity();
419 SerializePrologue(space, size, map);
420 // Serialize the rest of the object.
421 CHECK_EQ(0, bytes_processed_so_far_);
ulan 2017/04/06 17:53:08 Lines 413-421 are from the Serialize function. Th
422 bytes_processed_so_far_ = kPointerSize;
423 typedef v8::String::ExternalOneByteStringResource Resource;
424 Resource** resource_pointer = reinterpret_cast<Resource**>(
425 HeapObject::RawField(object_, ExternalString::kResourceOffset));
426
427 Address references_start = reinterpret_cast<Address>(resource_pointer);
428 OutputRawData(references_start);
429 if (!SerializeExternalNativeSourceString(
430 Natives::GetBuiltinsCount(), resource_pointer,
431 Natives::GetSourceCache(heap), kNativesStringResource)) {
432 bool result = SerializeExternalNativeSourceString(
433 ExtraNatives::GetBuiltinsCount(), resource_pointer,
434 ExtraNatives::GetSourceCache(heap), kExtraNativesStringResource);
435 // One of the strings in the natives cache should match the resource. We
436 // don't expect any other kinds of external strings here.
437 USE(result);
438 DCHECK(result);
439 }
440 OutputRawData(object_->address() + size);
441 }
442 }
443
444 bool Serializer::ObjectSerializer::SerializeExternalNativeSourceString(
445 int builtin_count,
446 v8::String::ExternalOneByteStringResource** resource_pointer,
447 FixedArray* source_cache, int resource_index) {
448 Isolate* isolate = serializer_->isolate();
ulan 2017/04/06 17:53:08 This function moved without any change.
449 for (int i = 0; i < builtin_count; i++) {
450 Object* source = source_cache->get(i);
451 if (!source->IsUndefined(isolate)) {
452 ExternalOneByteString* string = ExternalOneByteString::cast(source);
453 typedef v8::String::ExternalOneByteStringResource Resource;
454 const Resource* resource = string->resource();
455 if (resource == *resource_pointer) {
456 sink_->Put(resource_index, "NativesStringResource");
457 sink_->PutSection(i, "NativesStringResourceEnd");
458 bytes_processed_so_far_ += sizeof(resource);
459 return true;
460 }
461 }
462 }
463 return false;
464 }
465
466 void Serializer::ObjectSerializer::SerializeExternalStringAsSequentialString() {
404 // Instead of serializing this as an external string, we serialize 467 // Instead of serializing this as an external string, we serialize
405 // an imaginary sequential string with the same content. 468 // an imaginary sequential string with the same content.
406 Isolate* isolate = serializer_->isolate(); 469 Isolate* isolate = serializer_->isolate();
407 DCHECK(object_->IsExternalString()); 470 DCHECK(object_->IsExternalString());
408 DCHECK(object_->map() != isolate->heap()->native_source_string_map()); 471 DCHECK(object_->map() != isolate->heap()->native_source_string_map());
409 ExternalString* string = ExternalString::cast(object_); 472 ExternalString* string = ExternalString::cast(object_);
410 int length = string->length(); 473 int length = string->length();
411 Map* map; 474 Map* map;
412 int content_size; 475 int content_size;
413 int allocation_size; 476 int allocation_size;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 DisallowHeapAllocation no_gc_; 557 DisallowHeapAllocation no_gc_;
495 }; 558 };
496 559
497 void Serializer::ObjectSerializer::Serialize() { 560 void Serializer::ObjectSerializer::Serialize() {
498 if (FLAG_trace_serializer) { 561 if (FLAG_trace_serializer) {
499 PrintF(" Encoding heap object: "); 562 PrintF(" Encoding heap object: ");
500 object_->ShortPrint(); 563 object_->ShortPrint();
501 PrintF("\n"); 564 PrintF("\n");
502 } 565 }
503 566
504 // We cannot serialize typed array objects correctly. 567 if (object_->IsExternalString()) {
505 DCHECK(!object_->IsJSTypedArray()); 568 SerializeExternalString();
569 } else {
570 // We cannot serialize typed array objects correctly.
571 DCHECK(!object_->IsJSTypedArray());
506 572
507 // We don't expect fillers. 573 // We don't expect fillers.
508 DCHECK(!object_->IsFiller()); 574 DCHECK(!object_->IsFiller());
509 575
510 if (object_->IsScript()) { 576 if (object_->IsScript()) {
511 // Clear cached line ends. 577 // Clear cached line ends.
512 Object* undefined = serializer_->isolate()->heap()->undefined_value(); 578 Object* undefined = serializer_->isolate()->heap()->undefined_value();
513 Script::cast(object_)->set_line_ends(undefined); 579 Script::cast(object_)->set_line_ends(undefined);
514 } 580 }
515 581
516 if (object_->IsExternalString()) { 582 int size = object_->Size();
ulan 2017/04/06 17:53:08 This code just moved verbatim from 529.
517 Heap* heap = serializer_->isolate()->heap(); 583 Map* map = object_->map();
518 if (object_->map() != heap->native_source_string_map()) { 584 AllocationSpace space =
519 // Usually we cannot recreate resources for external strings. To work 585 MemoryChunk::FromAddress(object_->address())->owner()->identity();
520 // around this, external strings are serialized to look like ordinary 586 SerializePrologue(space, size, map);
521 // sequential strings. 587
522 // The exception are native source code strings, since we can recreate 588 // Serialize the rest of the object.
523 // their resources. In that case we fall through and leave it to 589 CHECK_EQ(0, bytes_processed_so_far_);
524 // VisitExternalOneByteString further down. 590 bytes_processed_so_far_ = kPointerSize;
525 SerializeExternalString(); 591
592 RecursionScope recursion(serializer_);
593 // Objects that are immediately post processed during deserialization
594 // cannot be deferred, since post processing requires the object content.
595 if (recursion.ExceedsMaximum() && CanBeDeferred(object_)) {
596 serializer_->QueueDeferredObject(object_);
597 sink_->Put(kDeferred, "Deferring object content");
526 return; 598 return;
527 } 599 }
600
601 UnlinkWeakNextScope unlink_weak_next(object_);
602
603 object_->IterateBody(map->instance_type(), size, this);
604 OutputRawData(object_->address() + size);
528 } 605 }
529
530 int size = object_->Size();
531 Map* map = object_->map();
532 AllocationSpace space =
533 MemoryChunk::FromAddress(object_->address())->owner()->identity();
534 SerializePrologue(space, size, map);
535
536 // Serialize the rest of the object.
537 CHECK_EQ(0, bytes_processed_so_far_);
538 bytes_processed_so_far_ = kPointerSize;
539
540 RecursionScope recursion(serializer_);
541 // Objects that are immediately post processed during deserialization
542 // cannot be deferred, since post processing requires the object content.
543 if (recursion.ExceedsMaximum() && CanBeDeferred(object_)) {
544 serializer_->QueueDeferredObject(object_);
545 sink_->Put(kDeferred, "Deferring object content");
546 return;
547 }
548
549 UnlinkWeakNextScope unlink_weak_next(object_);
550
551 object_->IterateBody(map->instance_type(), size, this);
552 OutputRawData(object_->address() + size);
553 } 606 }
554 607
555 void Serializer::ObjectSerializer::SerializeDeferred() { 608 void Serializer::ObjectSerializer::SerializeDeferred() {
556 if (FLAG_trace_serializer) { 609 if (FLAG_trace_serializer) {
557 PrintF(" Encoding deferred heap object: "); 610 PrintF(" Encoding deferred heap object: ");
558 object_->ShortPrint(); 611 object_->ShortPrint();
559 PrintF("\n"); 612 PrintF("\n");
560 } 613 }
561 614
562 int size = object_->Size(); 615 int size = object_->Size();
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 bytes_processed_so_far_ += kPointerSize; 761 bytes_processed_so_far_ += kPointerSize;
709 } 762 }
710 763
711 void Serializer::ObjectSerializer::VisitCell(RelocInfo* rinfo) { 764 void Serializer::ObjectSerializer::VisitCell(RelocInfo* rinfo) {
712 int skip = OutputRawData(rinfo->pc(), kCanReturnSkipInsteadOfSkipping); 765 int skip = OutputRawData(rinfo->pc(), kCanReturnSkipInsteadOfSkipping);
713 Cell* object = Cell::cast(rinfo->target_cell()); 766 Cell* object = Cell::cast(rinfo->target_cell());
714 serializer_->SerializeObject(object, kPlain, kInnerPointer, skip); 767 serializer_->SerializeObject(object, kPlain, kInnerPointer, skip);
715 bytes_processed_so_far_ += kPointerSize; 768 bytes_processed_so_far_ += kPointerSize;
716 } 769 }
717 770
718 bool Serializer::ObjectSerializer::SerializeExternalNativeSourceString(
719 int builtin_count,
720 v8::String::ExternalOneByteStringResource** resource_pointer,
721 FixedArray* source_cache, int resource_index) {
722 Isolate* isolate = serializer_->isolate();
723 for (int i = 0; i < builtin_count; i++) {
724 Object* source = source_cache->get(i);
725 if (!source->IsUndefined(isolate)) {
726 ExternalOneByteString* string = ExternalOneByteString::cast(source);
727 typedef v8::String::ExternalOneByteStringResource Resource;
728 const Resource* resource = string->resource();
729 if (resource == *resource_pointer) {
730 sink_->Put(resource_index, "NativesStringResource");
731 sink_->PutSection(i, "NativesStringResourceEnd");
732 bytes_processed_so_far_ += sizeof(resource);
733 return true;
734 }
735 }
736 }
737 return false;
738 }
739
740 void Serializer::ObjectSerializer::VisitExternalOneByteString(
741 v8::String::ExternalOneByteStringResource** resource_pointer) {
742 DCHECK_EQ(serializer_->isolate()->heap()->native_source_string_map(),
743 object_->map());
744 DCHECK(ExternalOneByteString::cast(object_)->is_short());
745 Address references_start = reinterpret_cast<Address>(resource_pointer);
746 OutputRawData(references_start);
747 if (SerializeExternalNativeSourceString(
748 Natives::GetBuiltinsCount(), resource_pointer,
749 Natives::GetSourceCache(serializer_->isolate()->heap()),
750 kNativesStringResource)) {
751 return;
752 }
753 if (SerializeExternalNativeSourceString(
754 ExtraNatives::GetBuiltinsCount(), resource_pointer,
755 ExtraNatives::GetSourceCache(serializer_->isolate()->heap()),
756 kExtraNativesStringResource)) {
757 return;
758 }
759 // One of the strings in the natives cache should match the resource. We
760 // don't expect any other kinds of external strings here.
761 UNREACHABLE();
762 }
763
764 Address Serializer::ObjectSerializer::PrepareCode() { 771 Address Serializer::ObjectSerializer::PrepareCode() {
765 Code* code = Code::cast(object_); 772 Code* code = Code::cast(object_);
766 if (FLAG_predictable) { 773 if (FLAG_predictable) {
767 // To make snapshots reproducible, we make a copy of the code object 774 // To make snapshots reproducible, we make a copy of the code object
768 // and wipe all pointers in the copy, which we then serialize. 775 // and wipe all pointers in the copy, which we then serialize.
769 code = serializer_->CopyCode(code); 776 code = serializer_->CopyCode(code);
770 int mode_mask = RelocInfo::kCodeTargetMask | 777 int mode_mask = RelocInfo::kCodeTargetMask |
771 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | 778 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
772 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | 779 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
773 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) | 780 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 if (to_skip != 0 && return_skip == kIgnoringReturn) { 833 if (to_skip != 0 && return_skip == kIgnoringReturn) {
827 sink_->Put(kSkip, "Skip"); 834 sink_->Put(kSkip, "Skip");
828 sink_->PutInt(to_skip, "SkipDistance"); 835 sink_->PutInt(to_skip, "SkipDistance");
829 to_skip = 0; 836 to_skip = 0;
830 } 837 }
831 return to_skip; 838 return to_skip;
832 } 839 }
833 840
834 } // namespace internal 841 } // namespace internal
835 } // namespace v8 842 } // namespace v8
OLDNEW
« no previous file with comments | « src/snapshot/serializer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698