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

Side by Side Diff: src/serialize.cc

Issue 654243003: Revert "Break deserializer reservations into chunks that fit onto a page." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « src/serialize.h ('k') | src/snapshot-common.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/base/platform/platform.h" 9 #include "src/base/platform/platform.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 Isolate* isolate_; 591 Isolate* isolate_;
592 }; 592 };
593 593
594 594
595 Deserializer::Deserializer(SnapshotByteSource* source) 595 Deserializer::Deserializer(SnapshotByteSource* source)
596 : isolate_(NULL), 596 : isolate_(NULL),
597 attached_objects_(NULL), 597 attached_objects_(NULL),
598 source_(source), 598 source_(source),
599 external_reference_decoder_(NULL), 599 external_reference_decoder_(NULL),
600 deserialized_large_objects_(0) { 600 deserialized_large_objects_(0) {
601 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0; 601 for (int i = 0; i < kNumberOfSpaces; i++) {
602 reservations_[i] = kUninitializedReservation;
603 }
602 } 604 }
603 605
604 606
605 void Deserializer::FlushICacheForNewCodeObjects() { 607 void Deserializer::FlushICacheForNewCodeObjects() {
606 PageIterator it(isolate_->heap()->code_space()); 608 PageIterator it(isolate_->heap()->code_space());
607 while (it.has_next()) { 609 while (it.has_next()) {
608 Page* p = it.next(); 610 Page* p = it.next();
609 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start()); 611 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start());
610 } 612 }
611 } 613 }
612 614
613 615
614 bool Deserializer::ReserveSpace() {
615 if (!isolate_->heap()->ReserveSpace(reservations_)) return false;
616 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
617 high_water_[i] = reservations_[i][0].start;
618 }
619 return true;
620 }
621
622
623 void Deserializer::Deserialize(Isolate* isolate) { 616 void Deserializer::Deserialize(Isolate* isolate) {
624 isolate_ = isolate; 617 isolate_ = isolate;
625 DCHECK(isolate_ != NULL); 618 DCHECK(isolate_ != NULL);
626 if (!ReserveSpace()) FatalProcessOutOfMemory("deserializing context"); 619 isolate_->heap()->ReserveSpace(reservations_, high_water_);
627 // No active threads. 620 // No active threads.
628 DCHECK_EQ(NULL, isolate_->thread_manager()->FirstThreadStateInUse()); 621 DCHECK_EQ(NULL, isolate_->thread_manager()->FirstThreadStateInUse());
629 // No active handles. 622 // No active handles.
630 DCHECK(isolate_->handle_scope_implementer()->blocks()->is_empty()); 623 DCHECK(isolate_->handle_scope_implementer()->blocks()->is_empty());
631 DCHECK_EQ(NULL, external_reference_decoder_); 624 DCHECK_EQ(NULL, external_reference_decoder_);
632 external_reference_decoder_ = new ExternalReferenceDecoder(isolate); 625 external_reference_decoder_ = new ExternalReferenceDecoder(isolate);
633 isolate_->heap()->IterateSmiRoots(this); 626 isolate_->heap()->IterateSmiRoots(this);
634 isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); 627 isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG);
635 isolate_->heap()->RepairFreeListsAfterBoot(); 628 isolate_->heap()->RepairFreeListsAfterBoot();
636 isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); 629 isolate_->heap()->IterateWeakRoots(this, VISIT_ALL);
(...skipping 21 matching lines...) Expand all
658 } 651 }
659 652
660 FlushICacheForNewCodeObjects(); 653 FlushICacheForNewCodeObjects();
661 654
662 // Issue code events for newly deserialized code objects. 655 // Issue code events for newly deserialized code objects.
663 LOG_CODE_EVENT(isolate_, LogCodeObjects()); 656 LOG_CODE_EVENT(isolate_, LogCodeObjects());
664 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); 657 LOG_CODE_EVENT(isolate_, LogCompiledFunctions());
665 } 658 }
666 659
667 660
668 void Deserializer::DeserializePartial(Isolate* isolate, Object** root, 661 void Deserializer::DeserializePartial(Isolate* isolate, Object** root) {
669 OnOOM on_oom) {
670 isolate_ = isolate; 662 isolate_ = isolate;
671 for (int i = NEW_SPACE; i < kNumberOfSpaces; i++) { 663 for (int i = NEW_SPACE; i < kNumberOfSpaces; i++) {
672 DCHECK(reservations_[i].length() > 0); 664 DCHECK(reservations_[i] != kUninitializedReservation);
673 } 665 }
674 if (!ReserveSpace()) { 666 Heap* heap = isolate->heap();
675 if (on_oom == FATAL_ON_OOM) FatalProcessOutOfMemory("deserialize context"); 667 heap->ReserveSpace(reservations_, high_water_);
676 *root = NULL;
677 return;
678 }
679 if (external_reference_decoder_ == NULL) { 668 if (external_reference_decoder_ == NULL) {
680 external_reference_decoder_ = new ExternalReferenceDecoder(isolate); 669 external_reference_decoder_ = new ExternalReferenceDecoder(isolate);
681 } 670 }
682 671
683 DisallowHeapAllocation no_gc; 672 DisallowHeapAllocation no_gc;
684 673
685 // Keep track of the code space start and end pointers in case new 674 // Keep track of the code space start and end pointers in case new
686 // code objects were unserialized 675 // code objects were unserialized
687 OldSpace* code_space = isolate_->heap()->code_space(); 676 OldSpace* code_space = isolate_->heap()->code_space();
688 Address start_address = code_space->top(); 677 Address start_address = code_space->top();
(...skipping 15 matching lines...) Expand all
704 } 693 }
705 if (attached_objects_) attached_objects_->Dispose(); 694 if (attached_objects_) attached_objects_->Dispose();
706 } 695 }
707 696
708 697
709 // This is called on the roots. It is the driver of the deserialization 698 // This is called on the roots. It is the driver of the deserialization
710 // process. It is also called on the body of each function. 699 // process. It is also called on the body of each function.
711 void Deserializer::VisitPointers(Object** start, Object** end) { 700 void Deserializer::VisitPointers(Object** start, Object** end) {
712 // The space must be new space. Any other space would cause ReadChunk to try 701 // The space must be new space. Any other space would cause ReadChunk to try
713 // to update the remembered using NULL as the address. 702 // to update the remembered using NULL as the address.
714 ReadData(start, end, NEW_SPACE, NULL); 703 ReadChunk(start, end, NEW_SPACE, NULL);
715 } 704 }
716 705
717 706
718 void Deserializer::RelinkAllocationSite(AllocationSite* site) { 707 void Deserializer::RelinkAllocationSite(AllocationSite* site) {
719 if (isolate_->heap()->allocation_sites_list() == Smi::FromInt(0)) { 708 if (isolate_->heap()->allocation_sites_list() == Smi::FromInt(0)) {
720 site->set_weak_next(isolate_->heap()->undefined_value()); 709 site->set_weak_next(isolate_->heap()->undefined_value());
721 } else { 710 } else {
722 site->set_weak_next(isolate_->heap()->allocation_sites_list()); 711 site->set_weak_next(isolate_->heap()->allocation_sites_list());
723 } 712 }
724 isolate_->heap()->set_allocation_sites_list(site); 713 isolate_->heap()->set_allocation_sites_list(site);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 Object** write_back) { 781 Object** write_back) {
793 int size = source_->GetInt() << kObjectAlignmentBits; 782 int size = source_->GetInt() << kObjectAlignmentBits;
794 Address address = Allocate(space_number, size); 783 Address address = Allocate(space_number, size);
795 HeapObject* obj = HeapObject::FromAddress(address); 784 HeapObject* obj = HeapObject::FromAddress(address);
796 isolate_->heap()->OnAllocationEvent(obj, size); 785 isolate_->heap()->OnAllocationEvent(obj, size);
797 Object** current = reinterpret_cast<Object**>(address); 786 Object** current = reinterpret_cast<Object**>(address);
798 Object** limit = current + (size >> kPointerSizeLog2); 787 Object** limit = current + (size >> kPointerSizeLog2);
799 if (FLAG_log_snapshot_positions) { 788 if (FLAG_log_snapshot_positions) {
800 LOG(isolate_, SnapshotPositionEvent(address, source_->position())); 789 LOG(isolate_, SnapshotPositionEvent(address, source_->position()));
801 } 790 }
802 ReadData(current, limit, space_number, address); 791 ReadChunk(current, limit, space_number, address);
803 792
804 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() 793 // TODO(mvstanton): consider treating the heap()->allocation_sites_list()
805 // as a (weak) root. If this root is relocated correctly, 794 // as a (weak) root. If this root is relocated correctly,
806 // RelinkAllocationSite() isn't necessary. 795 // RelinkAllocationSite() isn't necessary.
807 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); 796 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj));
808 797
809 // Fix up strings from serialized user code. 798 // Fix up strings from serialized user code.
810 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); 799 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj);
811 800
812 *write_back = obj; 801 *write_back = obj;
813 #ifdef DEBUG 802 #ifdef DEBUG
814 if (obj->IsCode()) { 803 if (obj->IsCode()) {
815 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE); 804 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE);
816 } else { 805 } else {
817 DCHECK(space_number != CODE_SPACE); 806 DCHECK(space_number != CODE_SPACE);
818 } 807 }
819 #endif 808 #endif
820 } 809 }
821 810
822 811
823 // We know the space requirements before deserialization and can 812 // We know the space requirements before deserialization and can
824 // pre-allocate that reserved space. During deserialization, all we need 813 // pre-allocate that reserved space. During deserialization, all we need
825 // to do is to bump up the pointer for each space in the reserved 814 // to do is to bump up the pointer for each space in the reserved
826 // space. This is also used for fixing back references. 815 // space. This is also used for fixing back references.
827 // We may have to split up the pre-allocation into several chunks
828 // because it would not fit onto a single page, we have to keep track
829 // of when to move to the next chunk.
830 // Since multiple large objects cannot be folded into one large object 816 // Since multiple large objects cannot be folded into one large object
831 // space allocation, we have to do an actual allocation when deserializing 817 // space allocation, we have to do an actual allocation when deserializing
832 // each large object. Instead of tracking offset for back references, we 818 // each large object. Instead of tracking offset for back references, we
833 // reference large objects by index. 819 // reference large objects by index.
834 Address Deserializer::Allocate(int space_index, int size) { 820 Address Deserializer::Allocate(int space_index, int size) {
835 if (space_index == LO_SPACE) { 821 if (space_index == LO_SPACE) {
836 AlwaysAllocateScope scope(isolate_); 822 AlwaysAllocateScope scope(isolate_);
837 LargeObjectSpace* lo_space = isolate_->heap()->lo_space(); 823 LargeObjectSpace* lo_space = isolate_->heap()->lo_space();
838 Executability exec = static_cast<Executability>(source_->Get()); 824 Executability exec = static_cast<Executability>(source_->GetInt());
839 AllocationResult result = lo_space->AllocateRaw(size, exec); 825 AllocationResult result = lo_space->AllocateRaw(size, exec);
840 HeapObject* obj = HeapObject::cast(result.ToObjectChecked()); 826 HeapObject* obj = HeapObject::cast(result.ToObjectChecked());
841 deserialized_large_objects_.Add(obj); 827 deserialized_large_objects_.Add(obj);
842 return obj->address(); 828 return obj->address();
843 } else { 829 } else {
844 DCHECK(space_index < kNumberOfPreallocatedSpaces); 830 DCHECK(space_index < kNumberOfPreallocatedSpaces);
845 Address address = high_water_[space_index]; 831 Address address = high_water_[space_index];
846 DCHECK_NE(NULL, address);
847 const Heap::Reservation& reservation = reservations_[space_index];
848 int chunk_index = current_chunk_[space_index];
849 if (address + size > reservation[chunk_index].end) {
850 // The last chunk size matches exactly the already deserialized data.
851 DCHECK_EQ(address, reservation[chunk_index].end);
852 // Move to next reserved chunk.
853 chunk_index = ++current_chunk_[space_index];
854 DCHECK_LT(chunk_index, reservation.length());
855 // Prepare for next allocation in the next chunk.
856 address = reservation[chunk_index].start;
857 } else {
858 high_water_[space_index] = address + size;
859 }
860 high_water_[space_index] = address + size; 832 high_water_[space_index] = address + size;
861 return address; 833 return address;
862 } 834 }
863 } 835 }
864 836
865 837
866 void Deserializer::ReadData(Object** current, Object** limit, int source_space, 838 void Deserializer::ReadChunk(Object** current,
867 Address current_object_address) { 839 Object** limit,
840 int source_space,
841 Address current_object_address) {
868 Isolate* const isolate = isolate_; 842 Isolate* const isolate = isolate_;
869 // Write barrier support costs around 1% in startup time. In fact there 843 // Write barrier support costs around 1% in startup time. In fact there
870 // are no new space objects in current boot snapshots, so it's not needed, 844 // are no new space objects in current boot snapshots, so it's not needed,
871 // but that may change. 845 // but that may change.
872 bool write_barrier_needed = (current_object_address != NULL && 846 bool write_barrier_needed = (current_object_address != NULL &&
873 source_space != NEW_SPACE && 847 source_space != NEW_SPACE &&
874 source_space != CELL_SPACE && 848 source_space != CELL_SPACE &&
875 source_space != PROPERTY_CELL_SPACE && 849 source_space != PROPERTY_CELL_SPACE &&
876 source_space != CODE_SPACE && 850 source_space != CODE_SPACE &&
877 source_space != OLD_DATA_SPACE); 851 source_space != OLD_DATA_SPACE);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ 883 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
910 } else if (where == kExternalReference) { \ 884 } else if (where == kExternalReference) { \
911 int skip = source_->GetInt(); \ 885 int skip = source_->GetInt(); \
912 current = reinterpret_cast<Object**>( \ 886 current = reinterpret_cast<Object**>( \
913 reinterpret_cast<Address>(current) + skip); \ 887 reinterpret_cast<Address>(current) + skip); \
914 int reference_id = source_->GetInt(); \ 888 int reference_id = source_->GetInt(); \
915 Address address = external_reference_decoder_->Decode(reference_id); \ 889 Address address = external_reference_decoder_->Decode(reference_id); \
916 new_object = reinterpret_cast<Object*>(address); \ 890 new_object = reinterpret_cast<Object*>(address); \
917 } else if (where == kBackref) { \ 891 } else if (where == kBackref) { \
918 emit_write_barrier = (space_number == NEW_SPACE); \ 892 emit_write_barrier = (space_number == NEW_SPACE); \
919 new_object = GetBackReferencedObject(data & kSpaceMask); \ 893 new_object = GetAddressFromEnd(data & kSpaceMask); \
920 if (deserializing_user_code()) { \ 894 if (deserializing_user_code()) { \
921 new_object = ProcessBackRefInSerializedCode(new_object); \ 895 new_object = ProcessBackRefInSerializedCode(new_object); \
922 } \ 896 } \
923 } else if (where == kBuiltin) { \ 897 } else if (where == kBuiltin) { \
924 DCHECK(deserializing_user_code()); \ 898 DCHECK(deserializing_user_code()); \
925 int builtin_id = source_->GetInt(); \ 899 int builtin_id = source_->GetInt(); \
926 DCHECK_LE(0, builtin_id); \ 900 DCHECK_LE(0, builtin_id); \
927 DCHECK_LT(builtin_id, Builtins::builtin_count); \ 901 DCHECK_LT(builtin_id, Builtins::builtin_count); \
928 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ 902 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \
929 new_object = isolate->builtins()->builtin(name); \ 903 new_object = isolate->builtins()->builtin(name); \
930 emit_write_barrier = false; \ 904 emit_write_barrier = false; \
931 } else if (where == kAttachedReference) { \ 905 } else if (where == kAttachedReference) { \
932 DCHECK(deserializing_user_code()); \ 906 DCHECK(deserializing_user_code()); \
933 int index = source_->GetInt(); \ 907 int index = source_->GetInt(); \
934 new_object = *attached_objects_->at(index); \ 908 new_object = *attached_objects_->at(index); \
935 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ 909 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
936 } else { \ 910 } else { \
937 DCHECK(where == kBackrefWithSkip); \ 911 DCHECK(where == kBackrefWithSkip); \
938 int skip = source_->GetInt(); \ 912 int skip = source_->GetInt(); \
939 current = reinterpret_cast<Object**>( \ 913 current = reinterpret_cast<Object**>( \
940 reinterpret_cast<Address>(current) + skip); \ 914 reinterpret_cast<Address>(current) + skip); \
941 emit_write_barrier = (space_number == NEW_SPACE); \ 915 emit_write_barrier = (space_number == NEW_SPACE); \
942 new_object = GetBackReferencedObject(data & kSpaceMask); \ 916 new_object = GetAddressFromEnd(data & kSpaceMask); \
943 if (deserializing_user_code()) { \ 917 if (deserializing_user_code()) { \
944 new_object = ProcessBackRefInSerializedCode(new_object); \ 918 new_object = ProcessBackRefInSerializedCode(new_object); \
945 } \ 919 } \
946 } \ 920 } \
947 if (within == kInnerPointer) { \ 921 if (within == kInnerPointer) { \
948 if (space_number != CODE_SPACE || new_object->IsCode()) { \ 922 if (space_number != CODE_SPACE || new_object->IsCode()) { \
949 Code* new_code_object = reinterpret_cast<Code*>(new_object); \ 923 Code* new_code_object = reinterpret_cast<Code*>(new_object); \
950 new_object = \ 924 new_object = \
951 reinterpret_cast<Object*>(new_code_object->instruction_start()); \ 925 reinterpret_cast<Object*>(new_code_object->instruction_start()); \
952 } else { \ 926 } else { \
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1240 1214
1241 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) 1215 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink)
1242 : isolate_(isolate), 1216 : isolate_(isolate),
1243 sink_(sink), 1217 sink_(sink),
1244 external_reference_encoder_(new ExternalReferenceEncoder(isolate)), 1218 external_reference_encoder_(new ExternalReferenceEncoder(isolate)),
1245 root_index_wave_front_(0), 1219 root_index_wave_front_(0),
1246 code_address_map_(NULL), 1220 code_address_map_(NULL),
1247 seen_large_objects_index_(0) { 1221 seen_large_objects_index_(0) {
1248 // The serializer is meant to be used only to generate initial heap images 1222 // The serializer is meant to be used only to generate initial heap images
1249 // from a context in which there is only one isolate. 1223 // from a context in which there is only one isolate.
1250 for (int i = 0; i < kNumberOfSpaces; i++) pending_chunk_[i] = 0; 1224 for (int i = 0; i < kNumberOfSpaces; i++) fullness_[i] = 0;
1251 } 1225 }
1252 1226
1253 1227
1254 Serializer::~Serializer() { 1228 Serializer::~Serializer() {
1255 delete external_reference_encoder_; 1229 delete external_reference_encoder_;
1256 if (code_address_map_ != NULL) delete code_address_map_; 1230 if (code_address_map_ != NULL) delete code_address_map_;
1257 } 1231 }
1258 1232
1259 1233
1260 void StartupSerializer::SerializeStrongReferences() { 1234 void StartupSerializer::SerializeStrongReferences() {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 for (int i = 0; i < kPointerSize; i++) { 1276 for (int i = 0; i < kPointerSize; i++) {
1303 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); 1277 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte");
1304 } 1278 }
1305 } else { 1279 } else {
1306 SerializeObject(*current, kPlain, kStartOfObject, 0); 1280 SerializeObject(*current, kPlain, kStartOfObject, 0);
1307 } 1281 }
1308 } 1282 }
1309 } 1283 }
1310 1284
1311 1285
1312 void Serializer::FinalizeAllocation() {
1313 DCHECK_EQ(0, completed_chunks_[LO_SPACE].length()); // Not yet finalized.
1314 for (int i = 0; i < kNumberOfSpaces; i++) {
1315 // Complete the last pending chunk and if there are no completed chunks,
1316 // make sure there is at least one empty chunk.
1317 if (pending_chunk_[i] > 0 || completed_chunks_[i].length() == 0) {
1318 completed_chunks_[i].Add(pending_chunk_[i]);
1319 pending_chunk_[i] = 0;
1320 }
1321 }
1322 }
1323
1324
1325 // This ensures that the partial snapshot cache keeps things alive during GC and 1286 // This ensures that the partial snapshot cache keeps things alive during GC and
1326 // tracks their movement. When it is called during serialization of the startup 1287 // tracks their movement. When it is called during serialization of the startup
1327 // snapshot nothing happens. When the partial (context) snapshot is created, 1288 // snapshot nothing happens. When the partial (context) snapshot is created,
1328 // this array is populated with the pointers that the partial snapshot will 1289 // this array is populated with the pointers that the partial snapshot will
1329 // need. As that happens we emit serialized objects to the startup snapshot 1290 // need. As that happens we emit serialized objects to the startup snapshot
1330 // that correspond to the elements of this cache array. On deserialization we 1291 // that correspond to the elements of this cache array. On deserialization we
1331 // therefore need to visit the cache array. This fills it up with pointers to 1292 // therefore need to visit the cache array. This fills it up with pointers to
1332 // deserialized objects. 1293 // deserialized objects.
1333 void SerializerDeserializer::Iterate(Isolate* isolate, 1294 void SerializerDeserializer::Iterate(Isolate* isolate,
1334 ObjectVisitor* visitor) { 1295 ObjectVisitor* visitor) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 } else { 1362 } else {
1402 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space, 1363 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space,
1403 "BackRefSerWithSkip"); 1364 "BackRefSerWithSkip");
1404 sink_->PutInt(skip, "BackRefSkipDistance"); 1365 sink_->PutInt(skip, "BackRefSkipDistance");
1405 } 1366 }
1406 1367
1407 if (space == LO_SPACE) { 1368 if (space == LO_SPACE) {
1408 int index = address_mapper_.MappedTo(heap_object); 1369 int index = address_mapper_.MappedTo(heap_object);
1409 sink_->PutInt(index, "large object index"); 1370 sink_->PutInt(index, "large object index");
1410 } else { 1371 } else {
1411 uint32_t existing_allocation = address_mapper_.MappedTo(heap_object); 1372 int address = address_mapper_.MappedTo(heap_object);
1373 int offset = CurrentAllocationAddress(space) - address;
1412 // Shift out the bits that are always 0. 1374 // Shift out the bits that are always 0.
1413 existing_allocation >>= kObjectAlignmentBits; 1375 offset >>= kObjectAlignmentBits;
1414 sink_->PutInt(existing_allocation, "allocation"); 1376 sink_->PutInt(offset, "offset");
1415 } 1377 }
1416 } 1378 }
1417 1379
1418 1380
1419 void StartupSerializer::SerializeObject( 1381 void StartupSerializer::SerializeObject(
1420 Object* o, 1382 Object* o,
1421 HowToCode how_to_code, 1383 HowToCode how_to_code,
1422 WhereToPoint where_to_point, 1384 WhereToPoint where_to_point,
1423 int skip) { 1385 int skip) {
1424 CHECK(o->IsHeapObject()); 1386 CHECK(o->IsHeapObject());
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1564 serializer_->code_address_map_->Lookup(object_->address()); 1526 serializer_->code_address_map_->Lookup(object_->address());
1565 LOG(serializer_->isolate_, 1527 LOG(serializer_->isolate_,
1566 CodeNameEvent(object_->address(), sink_->Position(), code_name)); 1528 CodeNameEvent(object_->address(), sink_->Position(), code_name));
1567 LOG(serializer_->isolate_, 1529 LOG(serializer_->isolate_,
1568 SnapshotPositionEvent(object_->address(), sink_->Position())); 1530 SnapshotPositionEvent(object_->address(), sink_->Position()));
1569 } 1531 }
1570 1532
1571 // Mark this object as already serialized. 1533 // Mark this object as already serialized.
1572 if (space == LO_SPACE) { 1534 if (space == LO_SPACE) {
1573 if (object_->IsCode()) { 1535 if (object_->IsCode()) {
1574 sink_->Put(EXECUTABLE, "executable large object"); 1536 sink_->PutInt(EXECUTABLE, "executable large object");
1575 } else { 1537 } else {
1576 sink_->Put(NOT_EXECUTABLE, "not executable large object"); 1538 sink_->PutInt(NOT_EXECUTABLE, "not executable large object");
1577 } 1539 }
1578 int index = serializer_->AllocateLargeObject(size); 1540 int index = serializer_->AllocateLargeObject(size);
1579 serializer_->address_mapper()->AddMapping(object_, index); 1541 serializer_->address_mapper()->AddMapping(object_, index);
1580 } else { 1542 } else {
1581 int allocation = serializer_->Allocate(space, size); 1543 int offset = serializer_->Allocate(space, size);
1582 serializer_->address_mapper()->AddMapping(object_, allocation); 1544 serializer_->address_mapper()->AddMapping(object_, offset);
1583 } 1545 }
1584 1546
1585 // Serialize the map (first word of the object). 1547 // Serialize the map (first word of the object).
1586 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0); 1548 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0);
1587 } 1549 }
1588 1550
1589 1551
1590 void Serializer::ObjectSerializer::SerializeExternalString() { 1552 void Serializer::ObjectSerializer::SerializeExternalString() {
1591 // Instead of serializing this as an external string, we serialize 1553 // Instead of serializing this as an external string, we serialize
1592 // an imaginary sequential string with the same content. 1554 // an imaginary sequential string with the same content.
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1898 if (object->GetHeap()->InSpace(object, s)) { 1860 if (object->GetHeap()->InSpace(object, s)) {
1899 DCHECK(i < kNumberOfSpaces); 1861 DCHECK(i < kNumberOfSpaces);
1900 return i; 1862 return i;
1901 } 1863 }
1902 } 1864 }
1903 UNREACHABLE(); 1865 UNREACHABLE();
1904 return 0; 1866 return 0;
1905 } 1867 }
1906 1868
1907 1869
1908 uint32_t Serializer::AllocateLargeObject(int size) { 1870 int Serializer::AllocateLargeObject(int size) {
1909 // Large objects are allocated one-by-one when deserializing. We do not 1871 fullness_[LO_SPACE] += size;
1910 // have to keep track of multiple chunks.
1911 pending_chunk_[LO_SPACE] += size;
1912 return seen_large_objects_index_++; 1872 return seen_large_objects_index_++;
1913 } 1873 }
1914 1874
1915 1875
1916 uint32_t Serializer::Allocate(int space, int size) { 1876 int Serializer::Allocate(int space, int size) {
1917 CHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); 1877 CHECK(space >= 0 && space < kNumberOfPreallocatedSpaces);
1918 DCHECK(size > 0 && size < Page::kMaxRegularHeapObjectSize); 1878 int allocation_address = fullness_[space];
1919 uint32_t new_chunk_size = pending_chunk_[space] + size; 1879 fullness_[space] = allocation_address + size;
1920 uint32_t allocation; 1880 return allocation_address;
1921 if (new_chunk_size > Page::kMaxRegularHeapObjectSize) {
1922 // The new chunk size would not fit onto a single page. Complete the
1923 // current chunk and start a new one.
1924 completed_chunks_[space].Add(pending_chunk_[space]);
1925 pending_chunk_[space] = 0;
1926 new_chunk_size = size;
1927 }
1928 // For back-referencing, each allocation is encoded as a combination
1929 // of chunk index and offset inside the chunk.
1930 allocation = ChunkIndexBits::encode(completed_chunks_[space].length()) |
1931 OffsetBits::encode(pending_chunk_[space]);
1932 pending_chunk_[space] = new_chunk_size;
1933 return allocation;
1934 } 1881 }
1935 1882
1936 1883
1937 int Serializer::SpaceAreaSize(int space) { 1884 int Serializer::SpaceAreaSize(int space) {
1938 if (space == CODE_SPACE) { 1885 if (space == CODE_SPACE) {
1939 return isolate_->memory_allocator()->CodePageAreaSize(); 1886 return isolate_->memory_allocator()->CodePageAreaSize();
1940 } else { 1887 } else {
1941 return Page::kPageSize - Page::kObjectStartOffset; 1888 return Page::kPageSize - Page::kObjectStartOffset;
1942 } 1889 }
1943 } 1890 }
(...skipping 25 matching lines...) Expand all
1969 ListSnapshotSink list_sink(&payload); 1916 ListSnapshotSink list_sink(&payload);
1970 DebugSnapshotSink debug_sink(&list_sink); 1917 DebugSnapshotSink debug_sink(&list_sink);
1971 SnapshotByteSink* sink = FLAG_trace_code_serializer 1918 SnapshotByteSink* sink = FLAG_trace_code_serializer
1972 ? static_cast<SnapshotByteSink*>(&debug_sink) 1919 ? static_cast<SnapshotByteSink*>(&debug_sink)
1973 : static_cast<SnapshotByteSink*>(&list_sink); 1920 : static_cast<SnapshotByteSink*>(&list_sink);
1974 CodeSerializer cs(isolate, sink, *source, info->code()); 1921 CodeSerializer cs(isolate, sink, *source, info->code());
1975 DisallowHeapAllocation no_gc; 1922 DisallowHeapAllocation no_gc;
1976 Object** location = Handle<Object>::cast(info).location(); 1923 Object** location = Handle<Object>::cast(info).location();
1977 cs.VisitPointer(location); 1924 cs.VisitPointer(location);
1978 cs.Pad(); 1925 cs.Pad();
1979 cs.FinalizeAllocation();
1980 1926
1981 SerializedCodeData data(&payload, &cs); 1927 SerializedCodeData data(&payload, &cs);
1982 ScriptData* script_data = data.GetScriptData(); 1928 ScriptData* script_data = data.GetScriptData();
1983 1929
1984 if (FLAG_profile_deserialization) { 1930 if (FLAG_profile_deserialization) {
1985 double ms = timer.Elapsed().InMillisecondsF(); 1931 double ms = timer.Elapsed().InMillisecondsF();
1986 int length = script_data->length(); 1932 int length = script_data->length();
1987 PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms); 1933 PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms);
1988 } 1934 }
1989 1935
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
2140 void CodeSerializer::SerializeSourceObject(HowToCode how_to_code, 2086 void CodeSerializer::SerializeSourceObject(HowToCode how_to_code,
2141 WhereToPoint where_to_point) { 2087 WhereToPoint where_to_point) {
2142 if (FLAG_trace_code_serializer) PrintF("Encoding source object\n"); 2088 if (FLAG_trace_code_serializer) PrintF("Encoding source object\n");
2143 2089
2144 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject); 2090 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject);
2145 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source"); 2091 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source");
2146 sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex"); 2092 sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex");
2147 } 2093 }
2148 2094
2149 2095
2150 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( 2096 Handle<SharedFunctionInfo> CodeSerializer::Deserialize(Isolate* isolate,
2151 Isolate* isolate, ScriptData* data, Handle<String> source) { 2097 ScriptData* data,
2098 Handle<String> source) {
2152 base::ElapsedTimer timer; 2099 base::ElapsedTimer timer;
2153 if (FLAG_profile_deserialization) timer.Start(); 2100 if (FLAG_profile_deserialization) timer.Start();
2154 2101
2155 Object* root; 2102 Object* root;
2156 2103
2157 { 2104 {
2158 HandleScope scope(isolate); 2105 HandleScope scope(isolate);
2159 2106
2160 SerializedCodeData scd(data, *source); 2107 SerializedCodeData scd(data, *source);
2161 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); 2108 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength());
2162 Deserializer deserializer(&payload); 2109 Deserializer deserializer(&payload);
2163
2164 STATIC_ASSERT(NEW_SPACE == 0); 2110 STATIC_ASSERT(NEW_SPACE == 0);
2165 int current_space = NEW_SPACE; 2111 for (int i = NEW_SPACE; i < kNumberOfSpaces; i++) {
2166 Vector<const SerializedCodeData::Reservation> res = scd.Reservations(); 2112 deserializer.set_reservation(i, scd.GetReservation(i));
2167 for (const auto& r : res) {
2168 deserializer.AddReservation(current_space, r.chunk_size());
2169 if (r.is_last_chunk()) current_space++;
2170 } 2113 }
2171 DCHECK_EQ(kNumberOfSpaces, current_space);
2172 2114
2173 // Prepare and register list of attached objects. 2115 // Prepare and register list of attached objects.
2174 Vector<const uint32_t> code_stub_keys = scd.CodeStubKeys(); 2116 Vector<const uint32_t> code_stub_keys = scd.CodeStubKeys();
2175 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New( 2117 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New(
2176 code_stub_keys.length() + kCodeStubsBaseIndex); 2118 code_stub_keys.length() + kCodeStubsBaseIndex);
2177 attached_objects[kSourceObjectIndex] = source; 2119 attached_objects[kSourceObjectIndex] = source;
2178 for (int i = 0; i < code_stub_keys.length(); i++) { 2120 for (int i = 0; i < code_stub_keys.length(); i++) {
2179 attached_objects[i + kCodeStubsBaseIndex] = 2121 attached_objects[i + kCodeStubsBaseIndex] =
2180 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked(); 2122 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked();
2181 } 2123 }
2182 deserializer.SetAttachedObjects(&attached_objects); 2124 deserializer.SetAttachedObjects(&attached_objects);
2183 2125
2184 // Deserialize. 2126 // Deserialize.
2185 deserializer.DeserializePartial(isolate, &root, Deserializer::NULL_ON_OOM); 2127 deserializer.DeserializePartial(isolate, &root);
2186 if (root == NULL) {
2187 // Deserializing may fail if the reservations cannot be fulfilled.
2188 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n");
2189 return MaybeHandle<SharedFunctionInfo>();
2190 }
2191 deserializer.FlushICacheForNewCodeObjects(); 2128 deserializer.FlushICacheForNewCodeObjects();
2192 } 2129 }
2193 2130
2194 if (FLAG_profile_deserialization) { 2131 if (FLAG_profile_deserialization) {
2195 double ms = timer.Elapsed().InMillisecondsF(); 2132 double ms = timer.Elapsed().InMillisecondsF();
2196 int length = data->length(); 2133 int length = data->length();
2197 PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms); 2134 PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms);
2198 } 2135 }
2199 Handle<SharedFunctionInfo> result(SharedFunctionInfo::cast(root), isolate); 2136 Handle<SharedFunctionInfo> result(SharedFunctionInfo::cast(root), isolate);
2200 result->set_deserialized(true); 2137 result->set_deserialized(true);
2201 return result; 2138 return result;
2202 } 2139 }
2203 2140
2204 2141
2205 SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs) 2142 SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs)
2206 : owns_script_data_(true) { 2143 : owns_script_data_(true) {
2207 DisallowHeapAllocation no_gc; 2144 DisallowHeapAllocation no_gc;
2208 List<uint32_t>* stub_keys = cs->stub_keys(); 2145 List<uint32_t>* stub_keys = cs->stub_keys();
2209 2146
2210 // Gather reservation chunk sizes.
2211 List<uint32_t> reservations(SerializerDeserializer::kNumberOfSpaces);
2212 STATIC_ASSERT(NEW_SPACE == 0);
2213 for (int i = 0; i < SerializerDeserializer::kNumberOfSpaces; i++) {
2214 Vector<const uint32_t> chunks = cs->FinalAllocationChunks(i);
2215 for (int j = 0; j < chunks.length(); j++) {
2216 DCHECK(i == LO_SPACE || chunks[j] < Page::kMaxRegularHeapObjectSize);
2217 uint32_t chunk = ChunkSizeBits::encode(chunks[j]) |
2218 IsLastChunkBits::encode(j == chunks.length() - 1);
2219 reservations.Add(chunk);
2220 }
2221 }
2222
2223 // Calculate sizes. 2147 // Calculate sizes.
2224 int reservation_size = reservations.length() * kInt32Size;
2225 int num_stub_keys = stub_keys->length(); 2148 int num_stub_keys = stub_keys->length();
2226 int stub_keys_size = stub_keys->length() * kInt32Size; 2149 int stub_keys_size = stub_keys->length() * kInt32Size;
2227 int data_length = 2150 int data_length = kHeaderSize + stub_keys_size + payload->length();
2228 kHeaderSize + reservation_size + stub_keys_size + payload->length();
2229 2151
2230 // Allocate backing store and create result data. 2152 // Allocate backing store and create result data.
2231 byte* data = NewArray<byte>(data_length); 2153 byte* data = NewArray<byte>(data_length);
2232 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); 2154 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment));
2233 script_data_ = new ScriptData(data, data_length); 2155 script_data_ = new ScriptData(data, data_length);
2234 script_data_->AcquireDataOwnership(); 2156 script_data_->AcquireDataOwnership();
2235 2157
2236 // Set header values. 2158 // Set header values.
2237 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); 2159 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source()));
2238 SetHeaderValue(kReservationsOffset, reservations.length());
2239 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); 2160 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys);
2240 SetHeaderValue(kPayloadLengthOffset, payload->length()); 2161 SetHeaderValue(kPayloadLengthOffset, payload->length());
2241 2162 STATIC_ASSERT(NEW_SPACE == 0);
2242 // Copy reservation chunk sizes. 2163 for (int i = 0; i < SerializerDeserializer::kNumberOfSpaces; i++) {
2243 CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()), 2164 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i));
2244 reservation_size); 2165 }
2245 2166
2246 // Copy code stub keys. 2167 // Copy code stub keys.
2247 CopyBytes(data + kHeaderSize + reservation_size, 2168 CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(stub_keys->begin()),
2248 reinterpret_cast<byte*>(stub_keys->begin()), stub_keys_size); 2169 stub_keys_size);
2249 2170
2250 // Copy serialized data. 2171 // Copy serialized data.
2251 CopyBytes(data + kHeaderSize + reservation_size + stub_keys_size, 2172 CopyBytes(data + kHeaderSize + stub_keys_size, payload->begin(),
2252 payload->begin(), static_cast<size_t>(payload->length())); 2173 static_cast<size_t>(payload->length()));
2253 } 2174 }
2254 2175
2255 2176
2256 bool SerializedCodeData::IsSane(String* source) { 2177 bool SerializedCodeData::IsSane(String* source) {
2257 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && 2178 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) &&
2258 PayloadLength() >= SharedFunctionInfo::kSize; 2179 PayloadLength() >= SharedFunctionInfo::kSize;
2259 } 2180 }
2260 2181
2261 2182
2262 int SerializedCodeData::CheckSum(String* string) { 2183 int SerializedCodeData::CheckSum(String* string) {
2263 int checksum = Version::Hash(); 2184 int checksum = Version::Hash();
2264 #ifdef DEBUG 2185 #ifdef DEBUG
2265 uint32_t seed = static_cast<uint32_t>(checksum); 2186 uint32_t seed = static_cast<uint32_t>(checksum);
2266 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); 2187 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed));
2267 #endif // DEBUG 2188 #endif // DEBUG
2268 return checksum; 2189 return checksum;
2269 } 2190 }
2270 } } // namespace v8::internal 2191 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/serialize.h ('k') | src/snapshot-common.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698