OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |