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

Side by Side Diff: src/serialize.cc

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