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

Side by Side Diff: src/serialize.cc

Issue 780833002: Revert of Encode reservation meta data in the snapshot blob. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@snapshotformat
Patch Set: Created 6 years 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/serialize.h ('k') | src/snapshot.h » ('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 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 const char* name, 604 const char* name,
605 int length) { 605 int length) {
606 address_to_name_map_.Insert(code->address(), name, length); 606 address_to_name_map_.Insert(code->address(), name, length);
607 } 607 }
608 608
609 NameMap address_to_name_map_; 609 NameMap address_to_name_map_;
610 Isolate* isolate_; 610 Isolate* isolate_;
611 }; 611 };
612 612
613 613
614 void Deserializer::DecodeReservation( 614 Deserializer::Deserializer(SnapshotByteSource* source)
615 Vector<const SerializedData::Reservation> res) { 615 : isolate_(NULL),
616 DCHECK_EQ(0, reservations_[NEW_SPACE].length()); 616 attached_objects_(NULL),
617 STATIC_ASSERT(NEW_SPACE == 0); 617 source_(source),
618 int current_space = NEW_SPACE; 618 external_reference_decoder_(NULL),
619 for (const auto& r : res) { 619 deserialized_large_objects_(0) {
620 reservations_[current_space].Add({r.chunk_size(), NULL, NULL});
621 if (r.is_last()) current_space++;
622 }
623 DCHECK_EQ(kNumberOfSpaces, current_space);
624 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0; 620 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0;
625 } 621 }
626 622
627 623
628 void Deserializer::FlushICacheForNewCodeObjects() { 624 void Deserializer::FlushICacheForNewCodeObjects() {
629 PageIterator it(isolate_->heap()->code_space()); 625 PageIterator it(isolate_->heap()->code_space());
630 while (it.has_next()) { 626 while (it.has_next()) {
631 Page* p = it.next(); 627 Page* p = it.next();
632 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start()); 628 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start());
633 } 629 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 709
714 // There's no code deserialized here. If this assert fires 710 // There's no code deserialized here. If this assert fires
715 // then that's changed and logging should be added to notify 711 // then that's changed and logging should be added to notify
716 // the profiler et al of the new code. 712 // the profiler et al of the new code.
717 CHECK_EQ(start_address, code_space->top()); 713 CHECK_EQ(start_address, code_space->top());
718 } 714 }
719 715
720 716
721 Deserializer::~Deserializer() { 717 Deserializer::~Deserializer() {
722 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed. 718 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed.
723 // DCHECK(source_.AtEOF()); 719 // DCHECK(source_->AtEOF());
724 if (external_reference_decoder_) { 720 if (external_reference_decoder_) {
725 delete external_reference_decoder_; 721 delete external_reference_decoder_;
726 external_reference_decoder_ = NULL; 722 external_reference_decoder_ = NULL;
727 } 723 }
728 if (attached_objects_) attached_objects_->Dispose(); 724 if (attached_objects_) attached_objects_->Dispose();
729 } 725 }
730 726
731 727
732 // This is called on the roots. It is the driver of the deserialization 728 // This is called on the roots. It is the driver of the deserialization
733 // process. It is also called on the body of each function. 729 // process. It is also called on the body of each function.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 return canonical; 790 return canonical;
795 } 791 }
796 } 792 }
797 return obj; 793 return obj;
798 } 794 }
799 795
800 796
801 HeapObject* Deserializer::GetBackReferencedObject(int space) { 797 HeapObject* Deserializer::GetBackReferencedObject(int space) {
802 HeapObject* obj; 798 HeapObject* obj;
803 if (space == LO_SPACE) { 799 if (space == LO_SPACE) {
804 uint32_t index = source_.GetInt(); 800 uint32_t index = source_->GetInt();
805 obj = deserialized_large_objects_[index]; 801 obj = deserialized_large_objects_[index];
806 } else { 802 } else {
807 BackReference back_reference(source_.GetInt()); 803 BackReference back_reference(source_->GetInt());
808 DCHECK(space < kNumberOfPreallocatedSpaces); 804 DCHECK(space < kNumberOfPreallocatedSpaces);
809 uint32_t chunk_index = back_reference.chunk_index(); 805 uint32_t chunk_index = back_reference.chunk_index();
810 DCHECK_LE(chunk_index, current_chunk_[space]); 806 DCHECK_LE(chunk_index, current_chunk_[space]);
811 uint32_t chunk_offset = back_reference.chunk_offset(); 807 uint32_t chunk_offset = back_reference.chunk_offset();
812 obj = HeapObject::FromAddress(reservations_[space][chunk_index].start + 808 obj = HeapObject::FromAddress(reservations_[space][chunk_index].start +
813 chunk_offset); 809 chunk_offset);
814 } 810 }
815 if (deserializing_user_code() && obj->IsInternalizedString()) { 811 if (deserializing_user_code() && obj->IsInternalizedString()) {
816 obj = String::cast(obj)->GetForwardedInternalizedString(); 812 obj = String::cast(obj)->GetForwardedInternalizedString();
817 } 813 }
818 hot_objects_.Add(obj); 814 hot_objects_.Add(obj);
819 return obj; 815 return obj;
820 } 816 }
821 817
822 818
823 // This routine writes the new object into the pointer provided and then 819 // This routine writes the new object into the pointer provided and then
824 // returns true if the new object was in young space and false otherwise. 820 // returns true if the new object was in young space and false otherwise.
825 // The reason for this strange interface is that otherwise the object is 821 // The reason for this strange interface is that otherwise the object is
826 // written very late, which means the FreeSpace map is not set up by the 822 // written very late, which means the FreeSpace map is not set up by the
827 // time we need to use it to mark the space at the end of a page free. 823 // time we need to use it to mark the space at the end of a page free.
828 void Deserializer::ReadObject(int space_number, Object** write_back) { 824 void Deserializer::ReadObject(int space_number, Object** write_back) {
829 Address address; 825 Address address;
830 HeapObject* obj; 826 HeapObject* obj;
831 int next_int = source_.GetInt(); 827 int next_int = source_->GetInt();
832 828
833 bool double_align = false; 829 bool double_align = false;
834 #ifndef V8_HOST_ARCH_64_BIT 830 #ifndef V8_HOST_ARCH_64_BIT
835 double_align = next_int == kDoubleAlignmentSentinel; 831 double_align = next_int == kDoubleAlignmentSentinel;
836 if (double_align) next_int = source_.GetInt(); 832 if (double_align) next_int = source_->GetInt();
837 #endif 833 #endif
838 834
839 DCHECK_NE(kDoubleAlignmentSentinel, next_int); 835 DCHECK_NE(kDoubleAlignmentSentinel, next_int);
840 int size = next_int << kObjectAlignmentBits; 836 int size = next_int << kObjectAlignmentBits;
841 int reserved_size = size + (double_align ? kPointerSize : 0); 837 int reserved_size = size + (double_align ? kPointerSize : 0);
842 address = Allocate(space_number, reserved_size); 838 address = Allocate(space_number, reserved_size);
843 obj = HeapObject::FromAddress(address); 839 obj = HeapObject::FromAddress(address);
844 if (double_align) { 840 if (double_align) {
845 obj = isolate_->heap()->DoubleAlignForDeserialization(obj, reserved_size); 841 obj = isolate_->heap()->DoubleAlignForDeserialization(obj, reserved_size);
846 address = obj->address(); 842 address = obj->address();
847 } 843 }
848 844
849 isolate_->heap()->OnAllocationEvent(obj, size); 845 isolate_->heap()->OnAllocationEvent(obj, size);
850 Object** current = reinterpret_cast<Object**>(address); 846 Object** current = reinterpret_cast<Object**>(address);
851 Object** limit = current + (size >> kPointerSizeLog2); 847 Object** limit = current + (size >> kPointerSizeLog2);
852 if (FLAG_log_snapshot_positions) { 848 if (FLAG_log_snapshot_positions) {
853 LOG(isolate_, SnapshotPositionEvent(address, source_.position())); 849 LOG(isolate_, SnapshotPositionEvent(address, source_->position()));
854 } 850 }
855 ReadData(current, limit, space_number, address); 851 ReadData(current, limit, space_number, address);
856 852
857 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() 853 // TODO(mvstanton): consider treating the heap()->allocation_sites_list()
858 // as a (weak) root. If this root is relocated correctly, 854 // as a (weak) root. If this root is relocated correctly,
859 // RelinkAllocationSite() isn't necessary. 855 // RelinkAllocationSite() isn't necessary.
860 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); 856 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj));
861 857
862 // Fix up strings from serialized user code. 858 // Fix up strings from serialized user code.
863 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); 859 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj);
(...skipping 17 matching lines...) Expand all
881 // because it would not fit onto a single page. We do not have to keep 877 // because it would not fit onto a single page. We do not have to keep
882 // track of when to move to the next chunk. An opcode will signal this. 878 // track of when to move to the next chunk. An opcode will signal this.
883 // Since multiple large objects cannot be folded into one large object 879 // Since multiple large objects cannot be folded into one large object
884 // space allocation, we have to do an actual allocation when deserializing 880 // space allocation, we have to do an actual allocation when deserializing
885 // each large object. Instead of tracking offset for back references, we 881 // each large object. Instead of tracking offset for back references, we
886 // reference large objects by index. 882 // reference large objects by index.
887 Address Deserializer::Allocate(int space_index, int size) { 883 Address Deserializer::Allocate(int space_index, int size) {
888 if (space_index == LO_SPACE) { 884 if (space_index == LO_SPACE) {
889 AlwaysAllocateScope scope(isolate_); 885 AlwaysAllocateScope scope(isolate_);
890 LargeObjectSpace* lo_space = isolate_->heap()->lo_space(); 886 LargeObjectSpace* lo_space = isolate_->heap()->lo_space();
891 Executability exec = static_cast<Executability>(source_.Get()); 887 Executability exec = static_cast<Executability>(source_->Get());
892 AllocationResult result = lo_space->AllocateRaw(size, exec); 888 AllocationResult result = lo_space->AllocateRaw(size, exec);
893 HeapObject* obj = HeapObject::cast(result.ToObjectChecked()); 889 HeapObject* obj = HeapObject::cast(result.ToObjectChecked());
894 deserialized_large_objects_.Add(obj); 890 deserialized_large_objects_.Add(obj);
895 return obj->address(); 891 return obj->address();
896 } else { 892 } else {
897 DCHECK(space_index < kNumberOfPreallocatedSpaces); 893 DCHECK(space_index < kNumberOfPreallocatedSpaces);
898 Address address = high_water_[space_index]; 894 Address address = high_water_[space_index];
899 DCHECK_NE(NULL, address); 895 DCHECK_NE(NULL, address);
900 high_water_[space_index] += size; 896 high_water_[space_index] += size;
901 #ifdef DEBUG 897 #ifdef DEBUG
(...skipping 13 matching lines...) Expand all
915 // Write barrier support costs around 1% in startup time. In fact there 911 // Write barrier support costs around 1% in startup time. In fact there
916 // are no new space objects in current boot snapshots, so it's not needed, 912 // are no new space objects in current boot snapshots, so it's not needed,
917 // but that may change. 913 // but that may change.
918 bool write_barrier_needed = (current_object_address != NULL && 914 bool write_barrier_needed = (current_object_address != NULL &&
919 source_space != NEW_SPACE && 915 source_space != NEW_SPACE &&
920 source_space != CELL_SPACE && 916 source_space != CELL_SPACE &&
921 source_space != PROPERTY_CELL_SPACE && 917 source_space != PROPERTY_CELL_SPACE &&
922 source_space != CODE_SPACE && 918 source_space != CODE_SPACE &&
923 source_space != OLD_DATA_SPACE); 919 source_space != OLD_DATA_SPACE);
924 while (current < limit) { 920 while (current < limit) {
925 byte data = source_.Get(); 921 byte data = source_->Get();
926 switch (data) { 922 switch (data) {
927 #define CASE_STATEMENT(where, how, within, space_number) \ 923 #define CASE_STATEMENT(where, how, within, space_number) \
928 case where + how + within + space_number: \ 924 case where + how + within + space_number: \
929 STATIC_ASSERT((where & ~kPointedToMask) == 0); \ 925 STATIC_ASSERT((where & ~kPointedToMask) == 0); \
930 STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \ 926 STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \
931 STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \ 927 STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \
932 STATIC_ASSERT((space_number & ~kSpaceMask) == 0); 928 STATIC_ASSERT((space_number & ~kSpaceMask) == 0);
933 929
934 #define CASE_BODY(where, how, within, space_number_if_any) \ 930 #define CASE_BODY(where, how, within, space_number_if_any) \
935 { \ 931 { \
936 bool emit_write_barrier = false; \ 932 bool emit_write_barrier = false; \
937 bool current_was_incremented = false; \ 933 bool current_was_incremented = false; \
938 int space_number = space_number_if_any == kAnyOldSpace \ 934 int space_number = space_number_if_any == kAnyOldSpace \
939 ? (data & kSpaceMask) \ 935 ? (data & kSpaceMask) \
940 : space_number_if_any; \ 936 : space_number_if_any; \
941 if (where == kNewObject && how == kPlain && within == kStartOfObject) { \ 937 if (where == kNewObject && how == kPlain && within == kStartOfObject) { \
942 ReadObject(space_number, current); \ 938 ReadObject(space_number, current); \
943 emit_write_barrier = (space_number == NEW_SPACE); \ 939 emit_write_barrier = (space_number == NEW_SPACE); \
944 } else { \ 940 } else { \
945 Object* new_object = NULL; /* May not be a real Object pointer. */ \ 941 Object* new_object = NULL; /* May not be a real Object pointer. */ \
946 if (where == kNewObject) { \ 942 if (where == kNewObject) { \
947 ReadObject(space_number, &new_object); \ 943 ReadObject(space_number, &new_object); \
948 } else if (where == kRootArray) { \ 944 } else if (where == kRootArray) { \
949 int root_id = source_.GetInt(); \ 945 int root_id = source_->GetInt(); \
950 new_object = isolate->heap()->roots_array_start()[root_id]; \ 946 new_object = isolate->heap()->roots_array_start()[root_id]; \
951 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ 947 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
952 } else if (where == kPartialSnapshotCache) { \ 948 } else if (where == kPartialSnapshotCache) { \
953 int cache_index = source_.GetInt(); \ 949 int cache_index = source_->GetInt(); \
954 new_object = isolate->serialize_partial_snapshot_cache()[cache_index]; \ 950 new_object = isolate->serialize_partial_snapshot_cache()[cache_index]; \
955 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ 951 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
956 } else if (where == kExternalReference) { \ 952 } else if (where == kExternalReference) { \
957 int skip = source_.GetInt(); \ 953 int skip = source_->GetInt(); \
958 current = reinterpret_cast<Object**>( \ 954 current = reinterpret_cast<Object**>( \
959 reinterpret_cast<Address>(current) + skip); \ 955 reinterpret_cast<Address>(current) + skip); \
960 int reference_id = source_.GetInt(); \ 956 int reference_id = source_->GetInt(); \
961 Address address = external_reference_decoder_->Decode(reference_id); \ 957 Address address = external_reference_decoder_->Decode(reference_id); \
962 new_object = reinterpret_cast<Object*>(address); \ 958 new_object = reinterpret_cast<Object*>(address); \
963 } else if (where == kBackref) { \ 959 } else if (where == kBackref) { \
964 emit_write_barrier = (space_number == NEW_SPACE); \ 960 emit_write_barrier = (space_number == NEW_SPACE); \
965 new_object = GetBackReferencedObject(data & kSpaceMask); \ 961 new_object = GetBackReferencedObject(data & kSpaceMask); \
966 } else if (where == kBuiltin) { \ 962 } else if (where == kBuiltin) { \
967 DCHECK(deserializing_user_code()); \ 963 DCHECK(deserializing_user_code()); \
968 int builtin_id = source_.GetInt(); \ 964 int builtin_id = source_->GetInt(); \
969 DCHECK_LE(0, builtin_id); \ 965 DCHECK_LE(0, builtin_id); \
970 DCHECK_LT(builtin_id, Builtins::builtin_count); \ 966 DCHECK_LT(builtin_id, Builtins::builtin_count); \
971 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ 967 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \
972 new_object = isolate->builtins()->builtin(name); \ 968 new_object = isolate->builtins()->builtin(name); \
973 emit_write_barrier = false; \ 969 emit_write_barrier = false; \
974 } else if (where == kAttachedReference) { \ 970 } else if (where == kAttachedReference) { \
975 DCHECK(deserializing_user_code()); \ 971 DCHECK(deserializing_user_code()); \
976 int index = source_.GetInt(); \ 972 int index = source_->GetInt(); \
977 new_object = *attached_objects_->at(index); \ 973 new_object = *attached_objects_->at(index); \
978 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ 974 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
979 } else { \ 975 } else { \
980 DCHECK(where == kBackrefWithSkip); \ 976 DCHECK(where == kBackrefWithSkip); \
981 int skip = source_.GetInt(); \ 977 int skip = source_->GetInt(); \
982 current = reinterpret_cast<Object**>( \ 978 current = reinterpret_cast<Object**>( \
983 reinterpret_cast<Address>(current) + skip); \ 979 reinterpret_cast<Address>(current) + skip); \
984 emit_write_barrier = (space_number == NEW_SPACE); \ 980 emit_write_barrier = (space_number == NEW_SPACE); \
985 new_object = GetBackReferencedObject(data & kSpaceMask); \ 981 new_object = GetBackReferencedObject(data & kSpaceMask); \
986 } \ 982 } \
987 if (within == kInnerPointer) { \ 983 if (within == kInnerPointer) { \
988 if (space_number != CODE_SPACE || new_object->IsCode()) { \ 984 if (space_number != CODE_SPACE || new_object->IsCode()) { \
989 Code* new_code_object = reinterpret_cast<Code*>(new_object); \ 985 Code* new_code_object = reinterpret_cast<Code*>(new_object); \
990 new_object = \ 986 new_object = \
991 reinterpret_cast<Object*>(new_code_object->instruction_start()); \ 987 reinterpret_cast<Object*>(new_code_object->instruction_start()); \
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 f(25) \ 1071 f(25) \
1076 f(26) \ 1072 f(26) \
1077 f(27) \ 1073 f(27) \
1078 f(28) \ 1074 f(28) \
1079 f(29) \ 1075 f(29) \
1080 f(30) \ 1076 f(30) \
1081 f(31) 1077 f(31)
1082 1078
1083 // We generate 15 cases and bodies that process special tags that combine 1079 // We generate 15 cases and bodies that process special tags that combine
1084 // the raw data tag and the length into one byte. 1080 // the raw data tag and the length into one byte.
1085 #define RAW_CASE(index) \ 1081 #define RAW_CASE(index) \
1086 case kRawData + index: { \ 1082 case kRawData + index: { \
1087 byte* raw_data_out = reinterpret_cast<byte*>(current); \ 1083 byte* raw_data_out = reinterpret_cast<byte*>(current); \
1088 source_.CopyRaw(raw_data_out, index* kPointerSize); \ 1084 source_->CopyRaw(raw_data_out, index * kPointerSize); \
1089 current = reinterpret_cast<Object**>(raw_data_out + index * kPointerSize); \ 1085 current = \
1090 break; \ 1086 reinterpret_cast<Object**>(raw_data_out + index * kPointerSize); \
1091 } 1087 break; \
1088 }
1092 COMMON_RAW_LENGTHS(RAW_CASE) 1089 COMMON_RAW_LENGTHS(RAW_CASE)
1093 #undef RAW_CASE 1090 #undef RAW_CASE
1094 1091
1095 // Deserialize a chunk of raw data that doesn't have one of the popular 1092 // Deserialize a chunk of raw data that doesn't have one of the popular
1096 // lengths. 1093 // lengths.
1097 case kRawData: { 1094 case kRawData: {
1098 int size = source_.GetInt(); 1095 int size = source_->GetInt();
1099 byte* raw_data_out = reinterpret_cast<byte*>(current); 1096 byte* raw_data_out = reinterpret_cast<byte*>(current);
1100 source_.CopyRaw(raw_data_out, size); 1097 source_->CopyRaw(raw_data_out, size);
1101 break; 1098 break;
1102 } 1099 }
1103 1100
1104 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance) 1101 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance)
1105 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance + 16) { 1102 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance + 16) {
1106 int root_id = RootArrayConstantFromByteCode(data); 1103 int root_id = RootArrayConstantFromByteCode(data);
1107 Object* object = isolate->heap()->roots_array_start()[root_id]; 1104 Object* object = isolate->heap()->roots_array_start()[root_id];
1108 DCHECK(!isolate->heap()->InNewSpace(object)); 1105 DCHECK(!isolate->heap()->InNewSpace(object));
1109 *current++ = object; 1106 *current++ = object;
1110 break; 1107 break;
1111 } 1108 }
1112 1109
1113 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance) 1110 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance)
1114 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) { 1111 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) {
1115 int root_id = RootArrayConstantFromByteCode(data); 1112 int root_id = RootArrayConstantFromByteCode(data);
1116 int skip = source_.GetInt(); 1113 int skip = source_->GetInt();
1117 current = reinterpret_cast<Object**>( 1114 current = reinterpret_cast<Object**>(
1118 reinterpret_cast<intptr_t>(current) + skip); 1115 reinterpret_cast<intptr_t>(current) + skip);
1119 Object* object = isolate->heap()->roots_array_start()[root_id]; 1116 Object* object = isolate->heap()->roots_array_start()[root_id];
1120 DCHECK(!isolate->heap()->InNewSpace(object)); 1117 DCHECK(!isolate->heap()->InNewSpace(object));
1121 *current++ = object; 1118 *current++ = object;
1122 break; 1119 break;
1123 } 1120 }
1124 1121
1125 case kVariableRepeat: { 1122 case kVariableRepeat: {
1126 int repeats = source_.GetInt(); 1123 int repeats = source_->GetInt();
1127 Object* object = current[-1]; 1124 Object* object = current[-1];
1128 DCHECK(!isolate->heap()->InNewSpace(object)); 1125 DCHECK(!isolate->heap()->InNewSpace(object));
1129 for (int i = 0; i < repeats; i++) current[i] = object; 1126 for (int i = 0; i < repeats; i++) current[i] = object;
1130 current += repeats; 1127 current += repeats;
1131 break; 1128 break;
1132 } 1129 }
1133 1130
1134 STATIC_ASSERT(kRootArrayNumberOfConstantEncodings == 1131 STATIC_ASSERT(kRootArrayNumberOfConstantEncodings ==
1135 Heap::kOldSpaceRoots); 1132 Heap::kOldSpaceRoots);
1136 STATIC_ASSERT(kMaxFixedRepeats == 15); 1133 STATIC_ASSERT(kMaxFixedRepeats == 15);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 CASE_STATEMENT(kAttachedReference, kPlain, kInnerPointer, 0) 1233 CASE_STATEMENT(kAttachedReference, kPlain, kInnerPointer, 0)
1237 CASE_BODY(kAttachedReference, kPlain, kInnerPointer, 0) 1234 CASE_BODY(kAttachedReference, kPlain, kInnerPointer, 0)
1238 CASE_STATEMENT(kAttachedReference, kFromCode, kInnerPointer, 0) 1235 CASE_STATEMENT(kAttachedReference, kFromCode, kInnerPointer, 0)
1239 CASE_BODY(kAttachedReference, kFromCode, kInnerPointer, 0) 1236 CASE_BODY(kAttachedReference, kFromCode, kInnerPointer, 0)
1240 1237
1241 #undef CASE_STATEMENT 1238 #undef CASE_STATEMENT
1242 #undef CASE_BODY 1239 #undef CASE_BODY
1243 #undef ALL_SPACES 1240 #undef ALL_SPACES
1244 1241
1245 case kSkip: { 1242 case kSkip: {
1246 int size = source_.GetInt(); 1243 int size = source_->GetInt();
1247 current = reinterpret_cast<Object**>( 1244 current = reinterpret_cast<Object**>(
1248 reinterpret_cast<intptr_t>(current) + size); 1245 reinterpret_cast<intptr_t>(current) + size);
1249 break; 1246 break;
1250 } 1247 }
1251 1248
1252 case kNativesStringResource: { 1249 case kNativesStringResource: {
1253 int index = source_.Get(); 1250 int index = source_->Get();
1254 Vector<const char> source_vector = Natives::GetRawScriptSource(index); 1251 Vector<const char> source_vector = Natives::GetRawScriptSource(index);
1255 NativesExternalStringResource* resource = 1252 NativesExternalStringResource* resource =
1256 new NativesExternalStringResource(isolate->bootstrapper(), 1253 new NativesExternalStringResource(isolate->bootstrapper(),
1257 source_vector.start(), 1254 source_vector.start(),
1258 source_vector.length()); 1255 source_vector.length());
1259 *current++ = reinterpret_cast<Object*>(resource); 1256 *current++ = reinterpret_cast<Object*>(resource);
1260 break; 1257 break;
1261 } 1258 }
1262 1259
1263 case kNextChunk: { 1260 case kNextChunk: {
1264 int space = source_.Get(); 1261 int space = source_->Get();
1265 DCHECK(space < kNumberOfPreallocatedSpaces); 1262 DCHECK(space < kNumberOfPreallocatedSpaces);
1266 int chunk_index = current_chunk_[space]; 1263 int chunk_index = current_chunk_[space];
1267 const Heap::Reservation& reservation = reservations_[space]; 1264 const Heap::Reservation& reservation = reservations_[space];
1268 // Make sure the current chunk is indeed exhausted. 1265 // Make sure the current chunk is indeed exhausted.
1269 CHECK_EQ(reservation[chunk_index].end, high_water_[space]); 1266 CHECK_EQ(reservation[chunk_index].end, high_water_[space]);
1270 // Move to next reserved chunk. 1267 // Move to next reserved chunk.
1271 chunk_index = ++current_chunk_[space]; 1268 chunk_index = ++current_chunk_[space];
1272 DCHECK_LT(chunk_index, reservation.length()); 1269 DCHECK_LT(chunk_index, reservation.length());
1273 high_water_[space] = reservation[chunk_index].start; 1270 high_water_[space] = reservation[chunk_index].start;
1274 break; 1271 break;
1275 } 1272 }
1276 1273
1277 FOUR_CASES(kHotObjectWithSkip) 1274 FOUR_CASES(kHotObjectWithSkip)
1278 FOUR_CASES(kHotObjectWithSkip + 4) { 1275 FOUR_CASES(kHotObjectWithSkip + 4) {
1279 int skip = source_.GetInt(); 1276 int skip = source_->GetInt();
1280 current = reinterpret_cast<Object**>( 1277 current = reinterpret_cast<Object**>(
1281 reinterpret_cast<Address>(current) + skip); 1278 reinterpret_cast<Address>(current) + skip);
1282 // Fall through. 1279 // Fall through.
1283 } 1280 }
1284 FOUR_CASES(kHotObject) 1281 FOUR_CASES(kHotObject)
1285 FOUR_CASES(kHotObject + 4) { 1282 FOUR_CASES(kHotObject + 4) {
1286 int index = data & kHotObjectIndexMask; 1283 int index = data & kHotObjectIndexMask;
1287 *current = hot_objects_.Get(index); 1284 *current = hot_objects_.Get(index);
1288 if (write_barrier_needed && isolate->heap()->InNewSpace(*current)) { 1285 if (write_barrier_needed && isolate->heap()->InNewSpace(*current)) {
1289 Address current_address = reinterpret_cast<Address>(current); 1286 Address current_address = reinterpret_cast<Address>(current);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 for (int i = 0; i < kPointerSize; i++) { 1387 for (int i = 0; i < kPointerSize; i++) {
1391 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); 1388 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte");
1392 } 1389 }
1393 } else { 1390 } else {
1394 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0); 1391 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0);
1395 } 1392 }
1396 } 1393 }
1397 } 1394 }
1398 1395
1399 1396
1400 void Serializer::EncodeReservations( 1397 void Serializer::FinalizeAllocation() {
1401 List<SerializedData::Reservation>* out) const {
1402 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) { 1398 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
1403 for (int j = 0; j < completed_chunks_[i].length(); j++) { 1399 // Complete the last pending chunk and if there are no completed chunks,
1404 out->Add(SerializedData::Reservation(completed_chunks_[i][j])); 1400 // make sure there is at least one empty chunk.
1401 if (pending_chunk_[i] > 0 || completed_chunks_[i].length() == 0) {
1402 completed_chunks_[i].Add(pending_chunk_[i]);
1403 pending_chunk_[i] = 0;
1405 } 1404 }
1406
1407 if (pending_chunk_[i] > 0 || completed_chunks_[i].length() == 0) {
1408 out->Add(SerializedData::Reservation(pending_chunk_[i]));
1409 }
1410 out->last().mark_as_last();
1411 } 1405 }
1412
1413 out->Add(SerializedData::Reservation(large_objects_total_size_));
1414 out->last().mark_as_last();
1415 } 1406 }
1416 1407
1417 1408
1418 // This ensures that the partial snapshot cache keeps things alive during GC and 1409 // This ensures that the partial snapshot cache keeps things alive during GC and
1419 // tracks their movement. When it is called during serialization of the startup 1410 // tracks their movement. When it is called during serialization of the startup
1420 // snapshot nothing happens. When the partial (context) snapshot is created, 1411 // snapshot nothing happens. When the partial (context) snapshot is created,
1421 // this array is populated with the pointers that the partial snapshot will 1412 // this array is populated with the pointers that the partial snapshot will
1422 // need. As that happens we emit serialized objects to the startup snapshot 1413 // need. As that happens we emit serialized objects to the startup snapshot
1423 // that correspond to the elements of this cache array. On deserialization we 1414 // that correspond to the elements of this cache array. On deserialization we
1424 // therefore need to visit the cache array. This fills it up with pointers to 1415 // therefore need to visit the cache array. This fills it up with pointers to
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1720 sink_->Put(kRawData, "RawDataForString"); 1711 sink_->Put(kRawData, "RawDataForString");
1721 sink_->PutInt(bytes_to_output, "length"); 1712 sink_->PutInt(bytes_to_output, "length");
1722 1713
1723 // Serialize string header (except for map). 1714 // Serialize string header (except for map).
1724 Address string_start = string->address(); 1715 Address string_start = string->address();
1725 for (int i = HeapObject::kHeaderSize; i < SeqString::kHeaderSize; i++) { 1716 for (int i = HeapObject::kHeaderSize; i < SeqString::kHeaderSize; i++) {
1726 sink_->PutSection(string_start[i], "StringHeader"); 1717 sink_->PutSection(string_start[i], "StringHeader");
1727 } 1718 }
1728 1719
1729 // Serialize string content. 1720 // Serialize string content.
1730 sink_->PutRaw(resource, content_size, "StringContent"); 1721 sink_->PutRaw(const_cast<byte*>(resource), content_size, "StringContent");
1731 1722
1732 // Since the allocation size is rounded up to object alignment, there 1723 // Since the allocation size is rounded up to object alignment, there
1733 // maybe left-over bytes that need to be padded. 1724 // maybe left-over bytes that need to be padded.
1734 int padding_size = allocation_size - SeqString::kHeaderSize - content_size; 1725 int padding_size = allocation_size - SeqString::kHeaderSize - content_size;
1735 DCHECK(0 <= padding_size && padding_size < kObjectAlignment); 1726 DCHECK(0 <= padding_size && padding_size < kObjectAlignment);
1736 for (int i = 0; i < padding_size; i++) sink_->PutSection(0, "StringPadding"); 1727 for (int i = 0; i < padding_size; i++) sink_->PutSection(0, "StringPadding");
1737 1728
1738 sink_->Put(kSkip, "SkipAfterString"); 1729 sink_->Put(kSkip, "SkipAfterString");
1739 sink_->PutInt(bytes_to_output, "SkipDistance"); 1730 sink_->PutInt(bytes_to_output, "SkipDistance");
1740 } 1731 }
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
2023 BackReference Serializer::Allocate(AllocationSpace space, int size) { 2014 BackReference Serializer::Allocate(AllocationSpace space, int size) {
2024 DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); 2015 DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces);
2025 DCHECK(size > 0 && size <= static_cast<int>(max_chunk_size(space))); 2016 DCHECK(size > 0 && size <= static_cast<int>(max_chunk_size(space)));
2026 uint32_t new_chunk_size = pending_chunk_[space] + size; 2017 uint32_t new_chunk_size = pending_chunk_[space] + size;
2027 if (new_chunk_size > max_chunk_size(space)) { 2018 if (new_chunk_size > max_chunk_size(space)) {
2028 // The new chunk size would not fit onto a single page. Complete the 2019 // The new chunk size would not fit onto a single page. Complete the
2029 // current chunk and start a new one. 2020 // current chunk and start a new one.
2030 sink_->Put(kNextChunk, "NextChunk"); 2021 sink_->Put(kNextChunk, "NextChunk");
2031 sink_->Put(space, "NextChunkSpace"); 2022 sink_->Put(space, "NextChunkSpace");
2032 completed_chunks_[space].Add(pending_chunk_[space]); 2023 completed_chunks_[space].Add(pending_chunk_[space]);
2033 DCHECK_LE(completed_chunks_[space].length(), BackReference::kMaxChunkIndex);
2034 pending_chunk_[space] = 0; 2024 pending_chunk_[space] = 0;
2035 new_chunk_size = size; 2025 new_chunk_size = size;
2036 } 2026 }
2037 uint32_t offset = pending_chunk_[space]; 2027 uint32_t offset = pending_chunk_[space];
2038 pending_chunk_[space] = new_chunk_size; 2028 pending_chunk_[space] = new_chunk_size;
2039 return BackReference::Reference(space, completed_chunks_[space].length(), 2029 return BackReference::Reference(space, completed_chunks_[space].length(),
2040 offset); 2030 offset);
2041 } 2031 }
2042 2032
2043 2033
(...skipping 24 matching lines...) Expand all
2068 PrintF("]\n"); 2058 PrintF("]\n");
2069 } 2059 }
2070 2060
2071 // Serialize code object. 2061 // Serialize code object.
2072 SnapshotByteSink sink(info->code()->CodeSize() * 2); 2062 SnapshotByteSink sink(info->code()->CodeSize() * 2);
2073 CodeSerializer cs(isolate, &sink, *source, info->code()); 2063 CodeSerializer cs(isolate, &sink, *source, info->code());
2074 DisallowHeapAllocation no_gc; 2064 DisallowHeapAllocation no_gc;
2075 Object** location = Handle<Object>::cast(info).location(); 2065 Object** location = Handle<Object>::cast(info).location();
2076 cs.VisitPointer(location); 2066 cs.VisitPointer(location);
2077 cs.Pad(); 2067 cs.Pad();
2068 cs.FinalizeAllocation();
2078 2069
2079 SerializedCodeData data(sink.data(), cs); 2070 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
2071 // Fail if any chunk index exceeds the limit.
2072 if (cs.FinalAllocationChunks(i).length() > BackReference::kMaxChunkIndex) {
2073 return NULL;
2074 }
2075 }
2076
2077 SerializedCodeData data(sink.data(), &cs);
2080 ScriptData* script_data = data.GetScriptData(); 2078 ScriptData* script_data = data.GetScriptData();
2081 2079
2082 if (FLAG_profile_deserialization) { 2080 if (FLAG_profile_deserialization) {
2083 double ms = timer.Elapsed().InMillisecondsF(); 2081 double ms = timer.Elapsed().InMillisecondsF();
2084 int length = script_data->length(); 2082 int length = script_data->length();
2085 PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms); 2083 PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms);
2086 } 2084 }
2087 2085
2088 return script_data; 2086 return script_data;
2089 } 2087 }
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
2270 { 2268 {
2271 HandleScope scope(isolate); 2269 HandleScope scope(isolate);
2272 2270
2273 SmartPointer<SerializedCodeData> scd( 2271 SmartPointer<SerializedCodeData> scd(
2274 SerializedCodeData::FromCachedData(cached_data, *source)); 2272 SerializedCodeData::FromCachedData(cached_data, *source));
2275 if (scd.is_empty()) { 2273 if (scd.is_empty()) {
2276 if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n"); 2274 if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n");
2277 DCHECK(cached_data->rejected()); 2275 DCHECK(cached_data->rejected());
2278 return MaybeHandle<SharedFunctionInfo>(); 2276 return MaybeHandle<SharedFunctionInfo>();
2279 } 2277 }
2278 SnapshotByteSource payload(scd->Payload(), scd->PayloadLength());
2279 Deserializer deserializer(&payload);
2280 2280
2281 // Eagerly expand string table to avoid allocations during deserialization. 2281 // Eagerly expand string table to avoid allocations during deserialization.
2282 StringTable::EnsureCapacityForDeserialization( 2282 StringTable::EnsureCapacityForDeserialization(
2283 isolate, scd->NumInternalizedStrings()); 2283 isolate, scd->NumInternalizedStrings());
2284 2284
2285 // Set reservations.
2286 STATIC_ASSERT(NEW_SPACE == 0);
2287 int current_space = NEW_SPACE;
2288 Vector<const SerializedCodeData::Reservation> res = scd->Reservations();
2289 for (const auto& r : res) {
2290 deserializer.AddReservation(current_space, r.chunk_size());
2291 if (r.is_last_chunk()) current_space++;
2292 }
2293 DCHECK_EQ(kNumberOfSpaces, current_space);
2294
2285 // Prepare and register list of attached objects. 2295 // Prepare and register list of attached objects.
2286 Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys(); 2296 Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys();
2287 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New( 2297 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New(
2288 code_stub_keys.length() + kCodeStubsBaseIndex); 2298 code_stub_keys.length() + kCodeStubsBaseIndex);
2289 attached_objects[kSourceObjectIndex] = source; 2299 attached_objects[kSourceObjectIndex] = source;
2290 for (int i = 0; i < code_stub_keys.length(); i++) { 2300 for (int i = 0; i < code_stub_keys.length(); i++) {
2291 attached_objects[i + kCodeStubsBaseIndex] = 2301 attached_objects[i + kCodeStubsBaseIndex] =
2292 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked(); 2302 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked();
2293 } 2303 }
2294
2295 Deserializer deserializer(scd.get());
2296 deserializer.SetAttachedObjects(&attached_objects); 2304 deserializer.SetAttachedObjects(&attached_objects);
2297 2305
2298 // Deserialize. 2306 // Deserialize.
2299 deserializer.DeserializePartial(isolate, &root, Deserializer::NULL_ON_OOM); 2307 deserializer.DeserializePartial(isolate, &root, Deserializer::NULL_ON_OOM);
2300 if (root == NULL) { 2308 if (root == NULL) {
2301 // Deserializing may fail if the reservations cannot be fulfilled. 2309 // Deserializing may fail if the reservations cannot be fulfilled.
2302 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); 2310 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n");
2303 return MaybeHandle<SharedFunctionInfo>(); 2311 return MaybeHandle<SharedFunctionInfo>();
2304 } 2312 }
2305 deserializer.FlushICacheForNewCodeObjects(); 2313 deserializer.FlushICacheForNewCodeObjects();
(...skipping 15 matching lines...) Expand all
2321 if (script->name()->IsString()) name = String::cast(script->name()); 2329 if (script->name()->IsString()) name = String::cast(script->name());
2322 } 2330 }
2323 isolate->logger()->CodeCreateEvent(Logger::SCRIPT_TAG, result->code(), 2331 isolate->logger()->CodeCreateEvent(Logger::SCRIPT_TAG, result->code(),
2324 *result, NULL, name); 2332 *result, NULL, name);
2325 } 2333 }
2326 2334
2327 return result; 2335 return result;
2328 } 2336 }
2329 2337
2330 2338
2331 void SerializedData::AllocateData(int size) {
2332 DCHECK(!owns_data_);
2333 data_ = NewArray<byte>(size);
2334 size_ = size;
2335 owns_data_ = true;
2336 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment));
2337 }
2338
2339
2340 SnapshotData::SnapshotData(const SnapshotByteSink& sink,
2341 const Serializer& ser) {
2342 DisallowHeapAllocation no_gc;
2343 List<Reservation> reservations;
2344 ser.EncodeReservations(&reservations);
2345 const List<byte>& payload = sink.data();
2346
2347 // Calculate sizes.
2348 int reservation_size = reservations.length() * kInt32Size;
2349 int size = kHeaderSize + reservation_size + payload.length();
2350
2351 // Allocate backing store and create result data.
2352 AllocateData(size);
2353
2354 // Set header values.
2355 SetHeaderValue(kCheckSumOffset, Version::Hash());
2356 SetHeaderValue(kReservationsOffset, reservations.length());
2357 SetHeaderValue(kPayloadLengthOffset, payload.length());
2358
2359 // Copy reservation chunk sizes.
2360 CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
2361 reservation_size);
2362
2363 // Copy serialized data.
2364 CopyBytes(data_ + kHeaderSize + reservation_size, payload.begin(),
2365 static_cast<size_t>(payload.length()));
2366 }
2367
2368
2369 bool SnapshotData::IsSane() {
2370 return GetHeaderValue(kCheckSumOffset) == Version::Hash();
2371 }
2372
2373
2374 Vector<const SerializedData::Reservation> SnapshotData::Reservations() const {
2375 return Vector<const Reservation>(
2376 reinterpret_cast<const Reservation*>(data_ + kHeaderSize),
2377 GetHeaderValue(kReservationsOffset));
2378 }
2379
2380
2381 Vector<const byte> SnapshotData::Payload() const {
2382 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
2383 const byte* payload = data_ + kHeaderSize + reservations_size;
2384 int length = GetHeaderValue(kPayloadLengthOffset);
2385 DCHECK_EQ(data_ + size_, payload + length);
2386 return Vector<const byte>(payload, length);
2387 }
2388
2389
2390 SerializedCodeData::SerializedCodeData(const List<byte>& payload, 2339 SerializedCodeData::SerializedCodeData(const List<byte>& payload,
2391 const CodeSerializer& cs) { 2340 CodeSerializer* cs)
2341 : script_data_(NULL), owns_script_data_(true) {
2392 DisallowHeapAllocation no_gc; 2342 DisallowHeapAllocation no_gc;
2393 const List<uint32_t>* stub_keys = cs.stub_keys(); 2343 List<uint32_t>* stub_keys = cs->stub_keys();
2394 2344
2395 List<Reservation> reservations; 2345 // Gather reservation chunk sizes.
2396 cs.EncodeReservations(&reservations); 2346 List<uint32_t> reservations(SerializerDeserializer::kNumberOfSpaces);
2347 STATIC_ASSERT(NEW_SPACE == 0);
2348 for (int i = 0; i < SerializerDeserializer::kNumberOfSpaces; i++) {
2349 Vector<const uint32_t> chunks = cs->FinalAllocationChunks(i);
2350 for (int j = 0; j < chunks.length(); j++) {
2351 uint32_t chunk = ChunkSizeBits::encode(chunks[j]) |
2352 IsLastChunkBits::encode(j == chunks.length() - 1);
2353 reservations.Add(chunk);
2354 }
2355 }
2397 2356
2398 // Calculate sizes. 2357 // Calculate sizes.
2399 int reservation_size = reservations.length() * kInt32Size; 2358 int reservation_size = reservations.length() * kInt32Size;
2400 int num_stub_keys = stub_keys->length(); 2359 int num_stub_keys = stub_keys->length();
2401 int stub_keys_size = stub_keys->length() * kInt32Size; 2360 int stub_keys_size = stub_keys->length() * kInt32Size;
2402 int size = kHeaderSize + reservation_size + stub_keys_size + payload.length(); 2361 int data_length =
2362 kHeaderSize + reservation_size + stub_keys_size + payload.length();
2403 2363
2404 // Allocate backing store and create result data. 2364 // Allocate backing store and create result data.
2405 AllocateData(size); 2365 byte* data = NewArray<byte>(data_length);
2366 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment));
2367 script_data_ = new ScriptData(data, data_length);
2368 script_data_->AcquireDataOwnership();
2406 2369
2407 // Set header values. 2370 // Set header values.
2408 SetHeaderValue(kCheckSumOffset, CheckSum(cs.source())); 2371 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source()));
2409 SetHeaderValue(kNumInternalizedStringsOffset, cs.num_internalized_strings()); 2372 SetHeaderValue(kNumInternalizedStringsOffset, cs->num_internalized_strings());
2410 SetHeaderValue(kReservationsOffset, reservations.length()); 2373 SetHeaderValue(kReservationsOffset, reservations.length());
2411 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); 2374 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys);
2412 SetHeaderValue(kPayloadLengthOffset, payload.length()); 2375 SetHeaderValue(kPayloadLengthOffset, payload.length());
2413 2376
2414 // Copy reservation chunk sizes. 2377 // Copy reservation chunk sizes.
2415 CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()), 2378 CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
2416 reservation_size); 2379 reservation_size);
2417 2380
2418 // Copy code stub keys. 2381 // Copy code stub keys.
2419 CopyBytes(data_ + kHeaderSize + reservation_size, 2382 CopyBytes(data + kHeaderSize + reservation_size,
2420 reinterpret_cast<byte*>(stub_keys->begin()), stub_keys_size); 2383 reinterpret_cast<byte*>(stub_keys->begin()), stub_keys_size);
2421 2384
2422 // Copy serialized data. 2385 // Copy serialized data.
2423 CopyBytes(data_ + kHeaderSize + reservation_size + stub_keys_size, 2386 CopyBytes(data + kHeaderSize + reservation_size + stub_keys_size,
2424 payload.begin(), static_cast<size_t>(payload.length())); 2387 payload.begin(), static_cast<size_t>(payload.length()));
2425 } 2388 }
2426 2389
2427 2390
2428 bool SerializedCodeData::IsSane(String* source) { 2391 bool SerializedCodeData::IsSane(String* source) {
2429 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && 2392 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) &&
2430 Payload().length() >= SharedFunctionInfo::kSize; 2393 PayloadLength() >= SharedFunctionInfo::kSize;
2431 } 2394 }
2432 2395
2433 2396
2434 int SerializedCodeData::CheckSum(String* string) { 2397 int SerializedCodeData::CheckSum(String* string) {
2435 return Version::Hash() ^ string->length(); 2398 return Version::Hash() ^ string->length();
2436 } 2399 }
2437
2438
2439 // Return ScriptData object and relinquish ownership over it to the caller.
2440 ScriptData* SerializedCodeData::GetScriptData() {
2441 DCHECK(owns_data_);
2442 ScriptData* result = new ScriptData(data_, size_);
2443 result->AcquireDataOwnership();
2444 owns_data_ = false;
2445 data_ = NULL;
2446 return result;
2447 }
2448
2449
2450 Vector<const SerializedData::Reservation> SerializedCodeData::Reservations()
2451 const {
2452 return Vector<const Reservation>(
2453 reinterpret_cast<const Reservation*>(data_ + kHeaderSize),
2454 GetHeaderValue(kReservationsOffset));
2455 }
2456
2457
2458 Vector<const byte> SerializedCodeData::Payload() const {
2459 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
2460 int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size;
2461 const byte* payload =
2462 data_ + kHeaderSize + reservations_size + code_stubs_size;
2463 int length = GetHeaderValue(kPayloadLengthOffset);
2464 DCHECK_EQ(data_ + size_, payload + length);
2465 return Vector<const byte>(payload, length);
2466 }
2467
2468
2469 int SerializedCodeData::NumInternalizedStrings() const {
2470 return GetHeaderValue(kNumInternalizedStringsOffset);
2471 }
2472
2473 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const {
2474 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
2475 const byte* start = data_ + kHeaderSize + reservations_size;
2476 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start),
2477 GetHeaderValue(kNumCodeStubKeysOffset));
2478 }
2479 } } // namespace v8::internal 2400 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/serialize.h ('k') | src/snapshot.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698