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

Side by Side Diff: src/serialize.cc

Issue 781443002: 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
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 Deserializer::Deserializer(SerializedData* sd)
615 : isolate_(NULL), 615 : isolate_(NULL),
616 attached_objects_(NULL), 616 attached_objects_(NULL),
617 source_(source), 617 source_(sd->Payload()),
618 external_reference_decoder_(NULL), 618 external_reference_decoder_(NULL),
619 deserialized_large_objects_(0) { 619 deserialized_large_objects_(0) {
620 // Set reservations.
621 STATIC_ASSERT(NEW_SPACE == 0);
622 int current_space = NEW_SPACE;
623 Vector<const SerializedData::Reservation> res = sd->Reservations();
624 for (const auto& r : res) {
625 reservations_[current_space].Add({r.chunk_size(), NULL, NULL});
626 if (r.is_last()) current_space++;
627 }
628 DCHECK_EQ(kNumberOfSpaces, current_space);
620 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0; 629 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0;
621 } 630 }
622 631
623 632
624 void Deserializer::FlushICacheForNewCodeObjects() { 633 void Deserializer::FlushICacheForNewCodeObjects() {
625 PageIterator it(isolate_->heap()->code_space()); 634 PageIterator it(isolate_->heap()->code_space());
626 while (it.has_next()) { 635 while (it.has_next()) {
627 Page* p = it.next(); 636 Page* p = it.next();
628 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start()); 637 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start());
629 } 638 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 718
710 // There's no code deserialized here. If this assert fires 719 // There's no code deserialized here. If this assert fires
711 // then that's changed and logging should be added to notify 720 // then that's changed and logging should be added to notify
712 // the profiler et al of the new code. 721 // the profiler et al of the new code.
713 CHECK_EQ(start_address, code_space->top()); 722 CHECK_EQ(start_address, code_space->top());
714 } 723 }
715 724
716 725
717 Deserializer::~Deserializer() { 726 Deserializer::~Deserializer() {
718 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed. 727 // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed.
719 // DCHECK(source_->AtEOF()); 728 // DCHECK(source_.AtEOF());
720 if (external_reference_decoder_) { 729 if (external_reference_decoder_) {
721 delete external_reference_decoder_; 730 delete external_reference_decoder_;
722 external_reference_decoder_ = NULL; 731 external_reference_decoder_ = NULL;
723 } 732 }
724 if (attached_objects_) attached_objects_->Dispose(); 733 if (attached_objects_) attached_objects_->Dispose();
725 } 734 }
726 735
727 736
728 // This is called on the roots. It is the driver of the deserialization 737 // 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. 738 // process. It is also called on the body of each function.
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 812
804 813
805 // This routine writes the new object into the pointer provided and then 814 // This routine writes the new object into the pointer provided and then
806 // returns true if the new object was in young space and false otherwise. 815 // returns true if the new object was in young space and false otherwise.
807 // The reason for this strange interface is that otherwise the object is 816 // The reason for this strange interface is that otherwise the object is
808 // written very late, which means the FreeSpace map is not set up by the 817 // written very late, which means the FreeSpace map is not set up by the
809 // time we need to use it to mark the space at the end of a page free. 818 // time we need to use it to mark the space at the end of a page free.
810 void Deserializer::ReadObject(int space_number, Object** write_back) { 819 void Deserializer::ReadObject(int space_number, Object** write_back) {
811 Address address; 820 Address address;
812 HeapObject* obj; 821 HeapObject* obj;
813 int next_int = source_->GetInt(); 822 int next_int = source_.GetInt();
814 823
815 bool double_align = false; 824 bool double_align = false;
816 #ifndef V8_HOST_ARCH_64_BIT 825 #ifndef V8_HOST_ARCH_64_BIT
817 double_align = next_int == kDoubleAlignmentSentinel; 826 double_align = next_int == kDoubleAlignmentSentinel;
818 if (double_align) next_int = source_->GetInt(); 827 if (double_align) next_int = source_.GetInt();
819 #endif 828 #endif
820 829
821 DCHECK_NE(kDoubleAlignmentSentinel, next_int); 830 DCHECK_NE(kDoubleAlignmentSentinel, next_int);
822 int size = next_int << kObjectAlignmentBits; 831 int size = next_int << kObjectAlignmentBits;
823 int reserved_size = size + (double_align ? kPointerSize : 0); 832 int reserved_size = size + (double_align ? kPointerSize : 0);
824 address = Allocate(space_number, reserved_size); 833 address = Allocate(space_number, reserved_size);
825 obj = HeapObject::FromAddress(address); 834 obj = HeapObject::FromAddress(address);
826 if (double_align) { 835 if (double_align) {
827 obj = isolate_->heap()->DoubleAlignForDeserialization(obj, reserved_size); 836 obj = isolate_->heap()->DoubleAlignForDeserialization(obj, reserved_size);
828 address = obj->address(); 837 address = obj->address();
829 } 838 }
830 839
831 isolate_->heap()->OnAllocationEvent(obj, size); 840 isolate_->heap()->OnAllocationEvent(obj, size);
832 Object** current = reinterpret_cast<Object**>(address); 841 Object** current = reinterpret_cast<Object**>(address);
833 Object** limit = current + (size >> kPointerSizeLog2); 842 Object** limit = current + (size >> kPointerSizeLog2);
834 if (FLAG_log_snapshot_positions) { 843 if (FLAG_log_snapshot_positions) {
835 LOG(isolate_, SnapshotPositionEvent(address, source_->position())); 844 LOG(isolate_, SnapshotPositionEvent(address, source_.position()));
836 } 845 }
837 ReadData(current, limit, space_number, address); 846 ReadData(current, limit, space_number, address);
838 847
839 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() 848 // TODO(mvstanton): consider treating the heap()->allocation_sites_list()
840 // as a (weak) root. If this root is relocated correctly, 849 // as a (weak) root. If this root is relocated correctly,
841 // RelinkAllocationSite() isn't necessary. 850 // RelinkAllocationSite() isn't necessary.
842 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); 851 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj));
843 852
844 // Fix up strings from serialized user code. 853 // Fix up strings from serialized user code.
845 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); 854 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj);
(...skipping 17 matching lines...) Expand all
863 // because it would not fit onto a single page. We do not have to keep 872 // because it would not fit onto a single page. We do not have to keep
864 // track of when to move to the next chunk. An opcode will signal this. 873 // track of when to move to the next chunk. An opcode will signal this.
865 // Since multiple large objects cannot be folded into one large object 874 // Since multiple large objects cannot be folded into one large object
866 // space allocation, we have to do an actual allocation when deserializing 875 // space allocation, we have to do an actual allocation when deserializing
867 // each large object. Instead of tracking offset for back references, we 876 // each large object. Instead of tracking offset for back references, we
868 // reference large objects by index. 877 // reference large objects by index.
869 Address Deserializer::Allocate(int space_index, int size) { 878 Address Deserializer::Allocate(int space_index, int size) {
870 if (space_index == LO_SPACE) { 879 if (space_index == LO_SPACE) {
871 AlwaysAllocateScope scope(isolate_); 880 AlwaysAllocateScope scope(isolate_);
872 LargeObjectSpace* lo_space = isolate_->heap()->lo_space(); 881 LargeObjectSpace* lo_space = isolate_->heap()->lo_space();
873 Executability exec = static_cast<Executability>(source_->Get()); 882 Executability exec = static_cast<Executability>(source_.Get());
874 AllocationResult result = lo_space->AllocateRaw(size, exec); 883 AllocationResult result = lo_space->AllocateRaw(size, exec);
875 HeapObject* obj = HeapObject::cast(result.ToObjectChecked()); 884 HeapObject* obj = HeapObject::cast(result.ToObjectChecked());
876 deserialized_large_objects_.Add(obj); 885 deserialized_large_objects_.Add(obj);
877 return obj->address(); 886 return obj->address();
878 } else { 887 } else {
879 DCHECK(space_index < kNumberOfPreallocatedSpaces); 888 DCHECK(space_index < kNumberOfPreallocatedSpaces);
880 Address address = high_water_[space_index]; 889 Address address = high_water_[space_index];
881 DCHECK_NE(NULL, address); 890 DCHECK_NE(NULL, address);
882 high_water_[space_index] += size; 891 high_water_[space_index] += size;
883 #ifdef DEBUG 892 #ifdef DEBUG
(...skipping 13 matching lines...) Expand all
897 // Write barrier support costs around 1% in startup time. In fact there 906 // Write barrier support costs around 1% in startup time. In fact there
898 // are no new space objects in current boot snapshots, so it's not needed, 907 // are no new space objects in current boot snapshots, so it's not needed,
899 // but that may change. 908 // but that may change.
900 bool write_barrier_needed = (current_object_address != NULL && 909 bool write_barrier_needed = (current_object_address != NULL &&
901 source_space != NEW_SPACE && 910 source_space != NEW_SPACE &&
902 source_space != CELL_SPACE && 911 source_space != CELL_SPACE &&
903 source_space != PROPERTY_CELL_SPACE && 912 source_space != PROPERTY_CELL_SPACE &&
904 source_space != CODE_SPACE && 913 source_space != CODE_SPACE &&
905 source_space != OLD_DATA_SPACE); 914 source_space != OLD_DATA_SPACE);
906 while (current < limit) { 915 while (current < limit) {
907 int data = source_->Get(); 916 int data = source_.Get();
908 switch (data) { 917 switch (data) {
909 #define CASE_STATEMENT(where, how, within, space_number) \ 918 #define CASE_STATEMENT(where, how, within, space_number) \
910 case where + how + within + space_number: \ 919 case where + how + within + space_number: \
911 STATIC_ASSERT((where & ~kPointedToMask) == 0); \ 920 STATIC_ASSERT((where & ~kPointedToMask) == 0); \
912 STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \ 921 STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \
913 STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \ 922 STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \
914 STATIC_ASSERT((space_number & ~kSpaceMask) == 0); 923 STATIC_ASSERT((space_number & ~kSpaceMask) == 0);
915 924
916 #define CASE_BODY(where, how, within, space_number_if_any) \ 925 #define CASE_BODY(where, how, within, space_number_if_any) \
917 { \ 926 { \
918 bool emit_write_barrier = false; \ 927 bool emit_write_barrier = false; \
919 bool current_was_incremented = false; \ 928 bool current_was_incremented = false; \
920 int space_number = space_number_if_any == kAnyOldSpace \ 929 int space_number = space_number_if_any == kAnyOldSpace \
921 ? (data & kSpaceMask) \ 930 ? (data & kSpaceMask) \
922 : space_number_if_any; \ 931 : space_number_if_any; \
923 if (where == kNewObject && how == kPlain && within == kStartOfObject) { \ 932 if (where == kNewObject && how == kPlain && within == kStartOfObject) { \
924 ReadObject(space_number, current); \ 933 ReadObject(space_number, current); \
925 emit_write_barrier = (space_number == NEW_SPACE); \ 934 emit_write_barrier = (space_number == NEW_SPACE); \
926 } else { \ 935 } else { \
927 Object* new_object = NULL; /* May not be a real Object pointer. */ \ 936 Object* new_object = NULL; /* May not be a real Object pointer. */ \
928 if (where == kNewObject) { \ 937 if (where == kNewObject) { \
929 ReadObject(space_number, &new_object); \ 938 ReadObject(space_number, &new_object); \
930 } else if (where == kRootArray) { \ 939 } else if (where == kRootArray) { \
931 int root_id = source_->GetInt(); \ 940 int root_id = source_.GetInt(); \
932 new_object = isolate->heap()->roots_array_start()[root_id]; \ 941 new_object = isolate->heap()->roots_array_start()[root_id]; \
933 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ 942 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
934 } else if (where == kPartialSnapshotCache) { \ 943 } else if (where == kPartialSnapshotCache) { \
935 int cache_index = source_->GetInt(); \ 944 int cache_index = source_.GetInt(); \
936 new_object = isolate->serialize_partial_snapshot_cache()[cache_index]; \ 945 new_object = isolate->serialize_partial_snapshot_cache()[cache_index]; \
937 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ 946 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
938 } else if (where == kExternalReference) { \ 947 } else if (where == kExternalReference) { \
939 int skip = source_->GetInt(); \ 948 int skip = source_.GetInt(); \
940 current = reinterpret_cast<Object**>( \ 949 current = reinterpret_cast<Object**>( \
941 reinterpret_cast<Address>(current) + skip); \ 950 reinterpret_cast<Address>(current) + skip); \
942 int reference_id = source_->GetInt(); \ 951 int reference_id = source_.GetInt(); \
943 Address address = external_reference_decoder_->Decode(reference_id); \ 952 Address address = external_reference_decoder_->Decode(reference_id); \
944 new_object = reinterpret_cast<Object*>(address); \ 953 new_object = reinterpret_cast<Object*>(address); \
945 } else if (where == kBackref) { \ 954 } else if (where == kBackref) { \
946 emit_write_barrier = (space_number == NEW_SPACE); \ 955 emit_write_barrier = (space_number == NEW_SPACE); \
947 new_object = GetBackReferencedObject(data & kSpaceMask); \ 956 new_object = GetBackReferencedObject(data & kSpaceMask); \
948 if (deserializing_user_code()) { \ 957 if (deserializing_user_code()) { \
949 new_object = ProcessBackRefInSerializedCode(new_object); \ 958 new_object = ProcessBackRefInSerializedCode(new_object); \
950 } \ 959 } \
951 } else if (where == kBuiltin) { \ 960 } else if (where == kBuiltin) { \
952 DCHECK(deserializing_user_code()); \ 961 DCHECK(deserializing_user_code()); \
953 int builtin_id = source_->GetInt(); \ 962 int builtin_id = source_.GetInt(); \
954 DCHECK_LE(0, builtin_id); \ 963 DCHECK_LE(0, builtin_id); \
955 DCHECK_LT(builtin_id, Builtins::builtin_count); \ 964 DCHECK_LT(builtin_id, Builtins::builtin_count); \
956 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ 965 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \
957 new_object = isolate->builtins()->builtin(name); \ 966 new_object = isolate->builtins()->builtin(name); \
958 emit_write_barrier = false; \ 967 emit_write_barrier = false; \
959 } else if (where == kAttachedReference) { \ 968 } else if (where == kAttachedReference) { \
960 DCHECK(deserializing_user_code()); \ 969 DCHECK(deserializing_user_code()); \
961 int index = source_->GetInt(); \ 970 int index = source_.GetInt(); \
962 new_object = *attached_objects_->at(index); \ 971 new_object = *attached_objects_->at(index); \
963 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ 972 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
964 } else { \ 973 } else { \
965 DCHECK(where == kBackrefWithSkip); \ 974 DCHECK(where == kBackrefWithSkip); \
966 int skip = source_->GetInt(); \ 975 int skip = source_.GetInt(); \
967 current = reinterpret_cast<Object**>( \ 976 current = reinterpret_cast<Object**>( \
968 reinterpret_cast<Address>(current) + skip); \ 977 reinterpret_cast<Address>(current) + skip); \
969 emit_write_barrier = (space_number == NEW_SPACE); \ 978 emit_write_barrier = (space_number == NEW_SPACE); \
970 new_object = GetBackReferencedObject(data & kSpaceMask); \ 979 new_object = GetBackReferencedObject(data & kSpaceMask); \
971 if (deserializing_user_code()) { \ 980 if (deserializing_user_code()) { \
972 new_object = ProcessBackRefInSerializedCode(new_object); \ 981 new_object = ProcessBackRefInSerializedCode(new_object); \
973 } \ 982 } \
974 } \ 983 } \
975 if (within == kInnerPointer) { \ 984 if (within == kInnerPointer) { \
976 if (space_number != CODE_SPACE || new_object->IsCode()) { \ 985 if (space_number != CODE_SPACE || new_object->IsCode()) { \
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 f(25) \ 1072 f(25) \
1064 f(26) \ 1073 f(26) \
1065 f(27) \ 1074 f(27) \
1066 f(28) \ 1075 f(28) \
1067 f(29) \ 1076 f(29) \
1068 f(30) \ 1077 f(30) \
1069 f(31) 1078 f(31)
1070 1079
1071 // We generate 15 cases and bodies that process special tags that combine 1080 // We generate 15 cases and bodies that process special tags that combine
1072 // the raw data tag and the length into one byte. 1081 // the raw data tag and the length into one byte.
1073 #define RAW_CASE(index) \ 1082 #define RAW_CASE(index) \
1074 case kRawData + index: { \ 1083 case kRawData + index: { \
1075 byte* raw_data_out = reinterpret_cast<byte*>(current); \ 1084 byte* raw_data_out = reinterpret_cast<byte*>(current); \
1076 source_->CopyRaw(raw_data_out, index * kPointerSize); \ 1085 source_.CopyRaw(raw_data_out, index* kPointerSize); \
1077 current = \ 1086 current = reinterpret_cast<Object**>(raw_data_out + index * kPointerSize); \
1078 reinterpret_cast<Object**>(raw_data_out + index * kPointerSize); \ 1087 break; \
1079 break; \ 1088 }
1080 }
1081 COMMON_RAW_LENGTHS(RAW_CASE) 1089 COMMON_RAW_LENGTHS(RAW_CASE)
1082 #undef RAW_CASE 1090 #undef RAW_CASE
1083 1091
1084 // 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
1085 // lengths. 1093 // lengths.
1086 case kRawData: { 1094 case kRawData: {
1087 int size = source_->GetInt(); 1095 int size = source_.GetInt();
1088 byte* raw_data_out = reinterpret_cast<byte*>(current); 1096 byte* raw_data_out = reinterpret_cast<byte*>(current);
1089 source_->CopyRaw(raw_data_out, size); 1097 source_.CopyRaw(raw_data_out, size);
1090 break; 1098 break;
1091 } 1099 }
1092 1100
1093 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance) 1101 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance)
1094 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance + 16) { 1102 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance + 16) {
1095 int root_id = RootArrayConstantFromByteCode(data); 1103 int root_id = RootArrayConstantFromByteCode(data);
1096 Object* object = isolate->heap()->roots_array_start()[root_id]; 1104 Object* object = isolate->heap()->roots_array_start()[root_id];
1097 DCHECK(!isolate->heap()->InNewSpace(object)); 1105 DCHECK(!isolate->heap()->InNewSpace(object));
1098 *current++ = object; 1106 *current++ = object;
1099 break; 1107 break;
1100 } 1108 }
1101 1109
1102 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance) 1110 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance)
1103 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) { 1111 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) {
1104 int root_id = RootArrayConstantFromByteCode(data); 1112 int root_id = RootArrayConstantFromByteCode(data);
1105 int skip = source_->GetInt(); 1113 int skip = source_.GetInt();
1106 current = reinterpret_cast<Object**>( 1114 current = reinterpret_cast<Object**>(
1107 reinterpret_cast<intptr_t>(current) + skip); 1115 reinterpret_cast<intptr_t>(current) + skip);
1108 Object* object = isolate->heap()->roots_array_start()[root_id]; 1116 Object* object = isolate->heap()->roots_array_start()[root_id];
1109 DCHECK(!isolate->heap()->InNewSpace(object)); 1117 DCHECK(!isolate->heap()->InNewSpace(object));
1110 *current++ = object; 1118 *current++ = object;
1111 break; 1119 break;
1112 } 1120 }
1113 1121
1114 case kRepeat: { 1122 case kRepeat: {
1115 int repeats = source_->GetInt(); 1123 int repeats = source_.GetInt();
1116 Object* object = current[-1]; 1124 Object* object = current[-1];
1117 DCHECK(!isolate->heap()->InNewSpace(object)); 1125 DCHECK(!isolate->heap()->InNewSpace(object));
1118 for (int i = 0; i < repeats; i++) current[i] = object; 1126 for (int i = 0; i < repeats; i++) current[i] = object;
1119 current += repeats; 1127 current += repeats;
1120 break; 1128 break;
1121 } 1129 }
1122 1130
1123 STATIC_ASSERT(kRootArrayNumberOfConstantEncodings == 1131 STATIC_ASSERT(kRootArrayNumberOfConstantEncodings ==
1124 Heap::kOldSpaceRoots); 1132 Heap::kOldSpaceRoots);
1125 STATIC_ASSERT(kMaxRepeats == 13); 1133 STATIC_ASSERT(kMaxRepeats == 13);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 CASE_STATEMENT(kAttachedReference, kPlain, kInnerPointer, 0) 1231 CASE_STATEMENT(kAttachedReference, kPlain, kInnerPointer, 0)
1224 CASE_BODY(kAttachedReference, kPlain, kInnerPointer, 0) 1232 CASE_BODY(kAttachedReference, kPlain, kInnerPointer, 0)
1225 CASE_STATEMENT(kAttachedReference, kFromCode, kInnerPointer, 0) 1233 CASE_STATEMENT(kAttachedReference, kFromCode, kInnerPointer, 0)
1226 CASE_BODY(kAttachedReference, kFromCode, kInnerPointer, 0) 1234 CASE_BODY(kAttachedReference, kFromCode, kInnerPointer, 0)
1227 1235
1228 #undef CASE_STATEMENT 1236 #undef CASE_STATEMENT
1229 #undef CASE_BODY 1237 #undef CASE_BODY
1230 #undef ALL_SPACES 1238 #undef ALL_SPACES
1231 1239
1232 case kSkip: { 1240 case kSkip: {
1233 int size = source_->GetInt(); 1241 int size = source_.GetInt();
1234 current = reinterpret_cast<Object**>( 1242 current = reinterpret_cast<Object**>(
1235 reinterpret_cast<intptr_t>(current) + size); 1243 reinterpret_cast<intptr_t>(current) + size);
1236 break; 1244 break;
1237 } 1245 }
1238 1246
1239 case kNativesStringResource: { 1247 case kNativesStringResource: {
1240 int index = source_->Get(); 1248 int index = source_.Get();
1241 Vector<const char> source_vector = Natives::GetRawScriptSource(index); 1249 Vector<const char> source_vector = Natives::GetRawScriptSource(index);
1242 NativesExternalStringResource* resource = 1250 NativesExternalStringResource* resource =
1243 new NativesExternalStringResource(isolate->bootstrapper(), 1251 new NativesExternalStringResource(isolate->bootstrapper(),
1244 source_vector.start(), 1252 source_vector.start(),
1245 source_vector.length()); 1253 source_vector.length());
1246 *current++ = reinterpret_cast<Object*>(resource); 1254 *current++ = reinterpret_cast<Object*>(resource);
1247 break; 1255 break;
1248 } 1256 }
1249 1257
1250 case kNextChunk: { 1258 case kNextChunk: {
1251 int space = source_->Get(); 1259 int space = source_.Get();
1252 DCHECK(space < kNumberOfPreallocatedSpaces); 1260 DCHECK(space < kNumberOfPreallocatedSpaces);
1253 int chunk_index = current_chunk_[space]; 1261 int chunk_index = current_chunk_[space];
1254 const Heap::Reservation& reservation = reservations_[space]; 1262 const Heap::Reservation& reservation = reservations_[space];
1255 // Make sure the current chunk is indeed exhausted. 1263 // Make sure the current chunk is indeed exhausted.
1256 CHECK_EQ(reservation[chunk_index].end, high_water_[space]); 1264 CHECK_EQ(reservation[chunk_index].end, high_water_[space]);
1257 // Move to next reserved chunk. 1265 // Move to next reserved chunk.
1258 chunk_index = ++current_chunk_[space]; 1266 chunk_index = ++current_chunk_[space];
1259 DCHECK_LT(chunk_index, reservation.length()); 1267 DCHECK_LT(chunk_index, reservation.length());
1260 high_water_[space] = reservation[chunk_index].start; 1268 high_water_[space] = reservation[chunk_index].start;
1261 break; 1269 break;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 for (int i = 0; i < kPointerSize; i++) { 1364 for (int i = 0; i < kPointerSize; i++) {
1357 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); 1365 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte");
1358 } 1366 }
1359 } else { 1367 } else {
1360 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0); 1368 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0);
1361 } 1369 }
1362 } 1370 }
1363 } 1371 }
1364 1372
1365 1373
1366 void Serializer::FinalizeAllocation() { 1374 void Serializer::EncodeReservations(
1375 List<SerializedData::Reservation>* out) const {
1367 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) { 1376 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
1368 // Complete the last pending chunk and if there are no completed chunks, 1377 for (int j = 0; j < completed_chunks_[i].length(); j++) {
1369 // make sure there is at least one empty chunk. 1378 out->Add(SerializedData::Reservation(completed_chunks_[i][j]));
1379 }
1380
1370 if (pending_chunk_[i] > 0 || completed_chunks_[i].length() == 0) { 1381 if (pending_chunk_[i] > 0 || completed_chunks_[i].length() == 0) {
1371 completed_chunks_[i].Add(pending_chunk_[i]); 1382 out->Add(SerializedData::Reservation(pending_chunk_[i]));
1372 pending_chunk_[i] = 0;
1373 } 1383 }
1384 out->last().mark_as_last();
1374 } 1385 }
1386
1387 out->Add(SerializedData::Reservation(large_objects_total_size_));
1388 out->last().mark_as_last();
1375 } 1389 }
1376 1390
1377 1391
1378 // This ensures that the partial snapshot cache keeps things alive during GC and 1392 // This ensures that the partial snapshot cache keeps things alive during GC and
1379 // tracks their movement. When it is called during serialization of the startup 1393 // tracks their movement. When it is called during serialization of the startup
1380 // snapshot nothing happens. When the partial (context) snapshot is created, 1394 // snapshot nothing happens. When the partial (context) snapshot is created,
1381 // this array is populated with the pointers that the partial snapshot will 1395 // this array is populated with the pointers that the partial snapshot will
1382 // need. As that happens we emit serialized objects to the startup snapshot 1396 // need. As that happens we emit serialized objects to the startup snapshot
1383 // that correspond to the elements of this cache array. On deserialization we 1397 // that correspond to the elements of this cache array. On deserialization we
1384 // therefore need to visit the cache array. This fills it up with pointers to 1398 // therefore need to visit the cache array. This fills it up with pointers to
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
1656 sink_->Put(kRawData, "RawDataForString"); 1670 sink_->Put(kRawData, "RawDataForString");
1657 sink_->PutInt(bytes_to_output, "length"); 1671 sink_->PutInt(bytes_to_output, "length");
1658 1672
1659 // Serialize string header (except for map). 1673 // Serialize string header (except for map).
1660 Address string_start = string->address(); 1674 Address string_start = string->address();
1661 for (int i = HeapObject::kHeaderSize; i < SeqString::kHeaderSize; i++) { 1675 for (int i = HeapObject::kHeaderSize; i < SeqString::kHeaderSize; i++) {
1662 sink_->PutSection(string_start[i], "StringHeader"); 1676 sink_->PutSection(string_start[i], "StringHeader");
1663 } 1677 }
1664 1678
1665 // Serialize string content. 1679 // Serialize string content.
1666 sink_->PutRaw(const_cast<byte*>(resource), content_size, "StringContent"); 1680 sink_->PutRaw(resource, content_size, "StringContent");
1667 1681
1668 // Since the allocation size is rounded up to object alignment, there 1682 // Since the allocation size is rounded up to object alignment, there
1669 // maybe left-over bytes that need to be padded. 1683 // maybe left-over bytes that need to be padded.
1670 int padding_size = allocation_size - SeqString::kHeaderSize - content_size; 1684 int padding_size = allocation_size - SeqString::kHeaderSize - content_size;
1671 DCHECK(0 <= padding_size && padding_size < kObjectAlignment); 1685 DCHECK(0 <= padding_size && padding_size < kObjectAlignment);
1672 for (int i = 0; i < padding_size; i++) sink_->PutSection(0, "StringPadding"); 1686 for (int i = 0; i < padding_size; i++) sink_->PutSection(0, "StringPadding");
1673 1687
1674 sink_->Put(kSkip, "SkipAfterString"); 1688 sink_->Put(kSkip, "SkipAfterString");
1675 sink_->PutInt(bytes_to_output, "SkipDistance"); 1689 sink_->PutInt(bytes_to_output, "SkipDistance");
1676 } 1690 }
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
1953 BackReference Serializer::Allocate(AllocationSpace space, int size) { 1967 BackReference Serializer::Allocate(AllocationSpace space, int size) {
1954 DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); 1968 DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces);
1955 DCHECK(size > 0 && size <= static_cast<int>(max_chunk_size(space))); 1969 DCHECK(size > 0 && size <= static_cast<int>(max_chunk_size(space)));
1956 uint32_t new_chunk_size = pending_chunk_[space] + size; 1970 uint32_t new_chunk_size = pending_chunk_[space] + size;
1957 if (new_chunk_size > max_chunk_size(space)) { 1971 if (new_chunk_size > max_chunk_size(space)) {
1958 // The new chunk size would not fit onto a single page. Complete the 1972 // The new chunk size would not fit onto a single page. Complete the
1959 // current chunk and start a new one. 1973 // current chunk and start a new one.
1960 sink_->Put(kNextChunk, "move to next chunk"); 1974 sink_->Put(kNextChunk, "move to next chunk");
1961 sink_->Put(space, "space of next chunk"); 1975 sink_->Put(space, "space of next chunk");
1962 completed_chunks_[space].Add(pending_chunk_[space]); 1976 completed_chunks_[space].Add(pending_chunk_[space]);
1977 DCHECK_LE(completed_chunks_[space].length(), BackReference::kMaxChunkIndex);
1963 pending_chunk_[space] = 0; 1978 pending_chunk_[space] = 0;
1964 new_chunk_size = size; 1979 new_chunk_size = size;
1965 } 1980 }
1966 uint32_t offset = pending_chunk_[space]; 1981 uint32_t offset = pending_chunk_[space];
1967 pending_chunk_[space] = new_chunk_size; 1982 pending_chunk_[space] = new_chunk_size;
1968 return BackReference::Reference(space, completed_chunks_[space].length(), 1983 return BackReference::Reference(space, completed_chunks_[space].length(),
1969 offset); 1984 offset);
1970 } 1985 }
1971 1986
1972 1987
(...skipping 24 matching lines...) Expand all
1997 PrintF("]\n"); 2012 PrintF("]\n");
1998 } 2013 }
1999 2014
2000 // Serialize code object. 2015 // Serialize code object.
2001 SnapshotByteSink sink(info->code()->CodeSize() * 2); 2016 SnapshotByteSink sink(info->code()->CodeSize() * 2);
2002 CodeSerializer cs(isolate, &sink, *source, info->code()); 2017 CodeSerializer cs(isolate, &sink, *source, info->code());
2003 DisallowHeapAllocation no_gc; 2018 DisallowHeapAllocation no_gc;
2004 Object** location = Handle<Object>::cast(info).location(); 2019 Object** location = Handle<Object>::cast(info).location();
2005 cs.VisitPointer(location); 2020 cs.VisitPointer(location);
2006 cs.Pad(); 2021 cs.Pad();
2007 cs.FinalizeAllocation();
2008 2022
2009 for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) { 2023 SerializedCodeData data(sink.data(), cs);
2010 // Fail if any chunk index exceeds the limit.
2011 if (cs.FinalAllocationChunks(i).length() > BackReference::kMaxChunkIndex) {
2012 return NULL;
2013 }
2014 }
2015
2016 SerializedCodeData data(sink.data(), &cs);
2017 ScriptData* script_data = data.GetScriptData(); 2024 ScriptData* script_data = data.GetScriptData();
2018 2025
2019 if (FLAG_profile_deserialization) { 2026 if (FLAG_profile_deserialization) {
2020 double ms = timer.Elapsed().InMillisecondsF(); 2027 double ms = timer.Elapsed().InMillisecondsF();
2021 int length = script_data->length(); 2028 int length = script_data->length();
2022 PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms); 2029 PrintF("[Serializing to %d bytes took %0.3f ms]\n", length, ms);
2023 } 2030 }
2024 2031
2025 return script_data; 2032 return script_data;
2026 } 2033 }
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
2233 { 2240 {
2234 HandleScope scope(isolate); 2241 HandleScope scope(isolate);
2235 2242
2236 SmartPointer<SerializedCodeData> scd( 2243 SmartPointer<SerializedCodeData> scd(
2237 SerializedCodeData::FromCachedData(cached_data, *source)); 2244 SerializedCodeData::FromCachedData(cached_data, *source));
2238 if (scd.is_empty()) { 2245 if (scd.is_empty()) {
2239 if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n"); 2246 if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n");
2240 DCHECK(cached_data->rejected()); 2247 DCHECK(cached_data->rejected());
2241 return MaybeHandle<SharedFunctionInfo>(); 2248 return MaybeHandle<SharedFunctionInfo>();
2242 } 2249 }
2243 SnapshotByteSource payload(scd->Payload(), scd->PayloadLength());
2244 Deserializer deserializer(&payload);
2245 2250
2246 // Eagerly expand string table to avoid allocations during deserialization. 2251 // Eagerly expand string table to avoid allocations during deserialization.
2247 StringTable::EnsureCapacityForDeserialization( 2252 StringTable::EnsureCapacityForDeserialization(
2248 isolate, scd->NumInternalizedStrings()); 2253 isolate, scd->NumInternalizedStrings());
2249 2254
2250 // Set reservations.
2251 STATIC_ASSERT(NEW_SPACE == 0);
2252 int current_space = NEW_SPACE;
2253 Vector<const SerializedCodeData::Reservation> res = scd->Reservations();
2254 for (const auto& r : res) {
2255 deserializer.AddReservation(current_space, r.chunk_size());
2256 if (r.is_last_chunk()) current_space++;
2257 }
2258 DCHECK_EQ(kNumberOfSpaces, current_space);
2259
2260 // Prepare and register list of attached objects. 2255 // Prepare and register list of attached objects.
2261 Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys(); 2256 Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys();
2262 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New( 2257 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New(
2263 code_stub_keys.length() + kCodeStubsBaseIndex); 2258 code_stub_keys.length() + kCodeStubsBaseIndex);
2264 attached_objects[kSourceObjectIndex] = source; 2259 attached_objects[kSourceObjectIndex] = source;
2265 for (int i = 0; i < code_stub_keys.length(); i++) { 2260 for (int i = 0; i < code_stub_keys.length(); i++) {
2266 attached_objects[i + kCodeStubsBaseIndex] = 2261 attached_objects[i + kCodeStubsBaseIndex] =
2267 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked(); 2262 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked();
2268 } 2263 }
2264
2265 Deserializer deserializer(scd.get());
2269 deserializer.SetAttachedObjects(&attached_objects); 2266 deserializer.SetAttachedObjects(&attached_objects);
2270 2267
2271 // Deserialize. 2268 // Deserialize.
2272 deserializer.DeserializePartial(isolate, &root, Deserializer::NULL_ON_OOM); 2269 deserializer.DeserializePartial(isolate, &root, Deserializer::NULL_ON_OOM);
2273 if (root == NULL) { 2270 if (root == NULL) {
2274 // Deserializing may fail if the reservations cannot be fulfilled. 2271 // Deserializing may fail if the reservations cannot be fulfilled.
2275 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n"); 2272 if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n");
2276 return MaybeHandle<SharedFunctionInfo>(); 2273 return MaybeHandle<SharedFunctionInfo>();
2277 } 2274 }
2278 deserializer.FlushICacheForNewCodeObjects(); 2275 deserializer.FlushICacheForNewCodeObjects();
(...skipping 15 matching lines...) Expand all
2294 if (script->name()->IsString()) name = String::cast(script->name()); 2291 if (script->name()->IsString()) name = String::cast(script->name());
2295 } 2292 }
2296 isolate->logger()->CodeCreateEvent(Logger::SCRIPT_TAG, result->code(), 2293 isolate->logger()->CodeCreateEvent(Logger::SCRIPT_TAG, result->code(),
2297 *result, NULL, name); 2294 *result, NULL, name);
2298 } 2295 }
2299 2296
2300 return result; 2297 return result;
2301 } 2298 }
2302 2299
2303 2300
2301 SnapshotData::SnapshotData(const SnapshotByteSink& sink,
2302 const Serializer& ser) {
2303 DisallowHeapAllocation no_gc;
2304 List<Reservation> reservations;
2305 ser.EncodeReservations(&reservations);
2306 const List<byte>& payload = sink.data();
2307
2308 // Calculate sizes.
2309 int reservation_size = reservations.length() * kInt32Size;
2310 size_ = kHeaderSize + reservation_size + payload.length();
2311
2312 // Allocate backing store and create result data.
2313 data_ = NewArray<byte>(size_);
vogelheim 2014/12/03 18:49:25 Related to the comment in serialize.h: I was tryi
Yang 2014/12/04 08:51:43 I moved allocation into a helper method in the par
2314 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment));
2315
2316 // Set header values.
2317 SetHeaderValue(kCheckSumOffset, Version::Hash());
2318 SetHeaderValue(kReservationsOffset, reservations.length());
2319 SetHeaderValue(kPayloadLengthOffset, payload.length());
2320
2321 // Copy reservation chunk sizes.
2322 CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
2323 reservation_size);
2324
2325 // Copy serialized data.
2326 CopyBytes(data_ + kHeaderSize + reservation_size, payload.begin(),
2327 static_cast<size_t>(payload.length()));
2328 }
2329
2330
2331 bool SnapshotData::IsSane() {
2332 return GetHeaderValue(kCheckSumOffset) == Version::Hash();
2333 }
2334
2335
2336 Vector<const SerializedData::Reservation> SnapshotData::Reservations() const {
2337 return Vector<const Reservation>(
2338 reinterpret_cast<const Reservation*>(data_ + kHeaderSize),
2339 GetHeaderValue(kReservationsOffset));
2340 }
2341
2342
2343 Vector<const byte> SnapshotData::Payload() const {
2344 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
2345 const byte* payload = data_ + kHeaderSize + reservations_size;
2346 int length = GetHeaderValue(kPayloadLengthOffset);
2347 DCHECK_EQ(data_ + size_, payload + length);
2348 return Vector<const byte>(payload, length);
2349 }
2350
2351
2304 SerializedCodeData::SerializedCodeData(const List<byte>& payload, 2352 SerializedCodeData::SerializedCodeData(const List<byte>& payload,
2305 CodeSerializer* cs) 2353 const CodeSerializer& cs) {
2306 : data_(NULL), size_(0), owns_script_data_(true) {
2307 DisallowHeapAllocation no_gc; 2354 DisallowHeapAllocation no_gc;
2308 List<uint32_t>* stub_keys = cs->stub_keys(); 2355 const List<uint32_t>* stub_keys = cs.stub_keys();
2309 2356
2310 // Gather reservation chunk sizes. 2357 List<Reservation> reservations;
2311 List<uint32_t> reservations(SerializerDeserializer::kNumberOfSpaces); 2358 cs.EncodeReservations(&reservations);
2312 STATIC_ASSERT(NEW_SPACE == 0);
2313 for (int i = 0; i < SerializerDeserializer::kNumberOfSpaces; i++) {
2314 Vector<const uint32_t> chunks = cs->FinalAllocationChunks(i);
2315 for (int j = 0; j < chunks.length(); j++) {
2316 uint32_t chunk = ChunkSizeBits::encode(chunks[j]) |
2317 IsLastChunkBits::encode(j == chunks.length() - 1);
2318 reservations.Add(chunk);
2319 }
2320 }
2321 2359
2322 // Calculate sizes. 2360 // Calculate sizes.
2323 int reservation_size = reservations.length() * kInt32Size; 2361 int reservation_size = reservations.length() * kInt32Size;
2324 int num_stub_keys = stub_keys->length(); 2362 int num_stub_keys = stub_keys->length();
2325 int stub_keys_size = stub_keys->length() * kInt32Size; 2363 int stub_keys_size = stub_keys->length() * kInt32Size;
2326 size_ = kHeaderSize + reservation_size + stub_keys_size + payload.length(); 2364 size_ = kHeaderSize + reservation_size + stub_keys_size + payload.length();
2327 2365
2328 // Allocate backing store and create result data. 2366 // Allocate backing store and create result data.
2329 data_ = NewArray<byte>(size_); 2367 data_ = NewArray<byte>(size_);
2330 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment)); 2368 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment));
2331 2369
2332 // Set header values. 2370 // Set header values.
2333 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); 2371 SetHeaderValue(kCheckSumOffset, CheckSum(cs.source()));
2334 SetHeaderValue(kNumInternalizedStringsOffset, cs->num_internalized_strings()); 2372 SetHeaderValue(kNumInternalizedStringsOffset, cs.num_internalized_strings());
2335 SetHeaderValue(kReservationsOffset, reservations.length()); 2373 SetHeaderValue(kReservationsOffset, reservations.length());
2336 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); 2374 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys);
2337 SetHeaderValue(kPayloadLengthOffset, payload.length()); 2375 SetHeaderValue(kPayloadLengthOffset, payload.length());
2338 2376
2339 // Copy reservation chunk sizes. 2377 // Copy reservation chunk sizes.
2340 CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()), 2378 CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
2341 reservation_size); 2379 reservation_size);
2342 2380
2343 // Copy code stub keys. 2381 // Copy code stub keys.
2344 CopyBytes(data_ + kHeaderSize + reservation_size, 2382 CopyBytes(data_ + kHeaderSize + reservation_size,
2345 reinterpret_cast<byte*>(stub_keys->begin()), stub_keys_size); 2383 reinterpret_cast<byte*>(stub_keys->begin()), stub_keys_size);
2346 2384
2347 // Copy serialized data. 2385 // Copy serialized data.
2348 CopyBytes(data_ + kHeaderSize + reservation_size + stub_keys_size, 2386 CopyBytes(data_ + kHeaderSize + reservation_size + stub_keys_size,
2349 payload.begin(), static_cast<size_t>(payload.length())); 2387 payload.begin(), static_cast<size_t>(payload.length()));
2350 } 2388 }
2351 2389
2352 2390
2353 bool SerializedCodeData::IsSane(String* source) { 2391 bool SerializedCodeData::IsSane(String* source) {
2354 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && 2392 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) &&
2355 PayloadLength() >= SharedFunctionInfo::kSize; 2393 Payload().length() >= SharedFunctionInfo::kSize;
2356 } 2394 }
2357 2395
2358 2396
2359 int SerializedCodeData::CheckSum(String* string) { 2397 int SerializedCodeData::CheckSum(String* string) {
2360 return Version::Hash() ^ string->length(); 2398 return Version::Hash() ^ string->length();
2361 } 2399 }
2400
2401
2402 // Return ScriptData object and relinquish ownership over it to the caller.
2403 ScriptData* SerializedCodeData::GetScriptData() {
2404 DCHECK(owns_data_);
2405 ScriptData* result = new ScriptData(data_, size_);
2406 result->AcquireDataOwnership();
2407 owns_data_ = false;
2408 return result;
vogelheim 2014/12/03 18:49:25 Is this expected to the last method call on a part
Yang 2014/12/04 08:51:43 Done.
2409 }
2410
2411
2412 Vector<const SerializedData::Reservation> SerializedCodeData::Reservations()
2413 const {
2414 return Vector<const Reservation>(
2415 reinterpret_cast<const Reservation*>(data_ + kHeaderSize),
2416 GetHeaderValue(kReservationsOffset));
2417 }
2418
2419
2420 Vector<const byte> SerializedCodeData::Payload() const {
2421 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
2422 int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size;
2423 const byte* payload =
2424 data_ + kHeaderSize + reservations_size + code_stubs_size;
2425 int length = GetHeaderValue(kPayloadLengthOffset);
2426 DCHECK_EQ(data_ + size_, payload + length);
2427 return Vector<const byte>(payload, length);
2428 }
2429
2430
2431 int SerializedCodeData::NumInternalizedStrings() const {
2432 return GetHeaderValue(kNumInternalizedStringsOffset);
2433 }
2434
2435 Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const {
2436 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
2437 const byte* start = data_ + kHeaderSize + reservations_size;
2438 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start),
2439 GetHeaderValue(kNumCodeStubKeysOffset));
2440 }
2362 } } // namespace v8::internal 2441 } } // namespace v8::internal
OLDNEW
« src/serialize.h ('K') | « src/serialize.h ('k') | src/snapshot.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698