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 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
833 // are no new space objects in current boot snapshots, so it's not needed, | 833 // are no new space objects in current boot snapshots, so it's not needed, |
834 // but that may change. | 834 // but that may change. |
835 bool write_barrier_needed = | 835 bool write_barrier_needed = |
836 (current_object_address != NULL && source_space != NEW_SPACE && | 836 (current_object_address != NULL && source_space != NEW_SPACE && |
837 source_space != CELL_SPACE && source_space != CODE_SPACE); | 837 source_space != CELL_SPACE && source_space != CODE_SPACE); |
838 while (current < limit) { | 838 while (current < limit) { |
839 byte data = source_.Get(); | 839 byte data = source_.Get(); |
840 switch (data) { | 840 switch (data) { |
841 #define CASE_STATEMENT(where, how, within, space_number) \ | 841 #define CASE_STATEMENT(where, how, within, space_number) \ |
842 case where + how + within + space_number: \ | 842 case where + how + within + space_number: \ |
843 STATIC_ASSERT((where & ~kPointedToMask) == 0); \ | 843 STATIC_ASSERT((where & ~kWhereMask) == 0); \ |
844 STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \ | 844 STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \ |
845 STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \ | 845 STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \ |
846 STATIC_ASSERT((space_number & ~kSpaceMask) == 0); | 846 STATIC_ASSERT((space_number & ~kSpaceMask) == 0); |
847 | 847 |
848 #define CASE_BODY(where, how, within, space_number_if_any) \ | 848 #define CASE_BODY(where, how, within, space_number_if_any) \ |
849 { \ | 849 { \ |
850 bool emit_write_barrier = false; \ | 850 bool emit_write_barrier = false; \ |
851 bool current_was_incremented = false; \ | 851 bool current_was_incremented = false; \ |
852 int space_number = space_number_if_any == kAnyOldSpace \ | 852 int space_number = space_number_if_any == kAnyOldSpace \ |
853 ? (data & kSpaceMask) \ | 853 ? (data & kSpaceMask) \ |
854 : space_number_if_any; \ | 854 : space_number_if_any; \ |
855 if (where == kNewObject && how == kPlain && within == kStartOfObject) { \ | 855 if (where == kNewObject && how == kPlain && within == kStartOfObject) { \ |
856 ReadObject(space_number, current); \ | 856 ReadObject(space_number, current); \ |
857 emit_write_barrier = (space_number == NEW_SPACE); \ | 857 emit_write_barrier = (space_number == NEW_SPACE); \ |
858 } else { \ | 858 } else { \ |
859 Object* new_object = NULL; /* May not be a real Object pointer. */ \ | 859 Object* new_object = NULL; /* May not be a real Object pointer. */ \ |
860 if (where == kNewObject) { \ | 860 if (where == kNewObject) { \ |
861 ReadObject(space_number, &new_object); \ | 861 ReadObject(space_number, &new_object); \ |
| 862 } else if (where == kBackref) { \ |
| 863 emit_write_barrier = (space_number == NEW_SPACE); \ |
| 864 new_object = GetBackReferencedObject(data & kSpaceMask); \ |
| 865 } else if (where == kBackrefWithSkip) { \ |
| 866 int skip = source_.GetInt(); \ |
| 867 current = reinterpret_cast<Object**>( \ |
| 868 reinterpret_cast<Address>(current) + skip); \ |
| 869 emit_write_barrier = (space_number == NEW_SPACE); \ |
| 870 new_object = GetBackReferencedObject(data & kSpaceMask); \ |
862 } else if (where == kRootArray) { \ | 871 } else if (where == kRootArray) { \ |
863 int root_id = source_.GetInt(); \ | 872 int root_id = source_.GetInt(); \ |
864 new_object = isolate->heap()->roots_array_start()[root_id]; \ | 873 new_object = isolate->heap()->roots_array_start()[root_id]; \ |
865 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ | 874 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ |
866 } else if (where == kPartialSnapshotCache) { \ | 875 } else if (where == kPartialSnapshotCache) { \ |
867 int cache_index = source_.GetInt(); \ | 876 int cache_index = source_.GetInt(); \ |
868 new_object = isolate->partial_snapshot_cache()->at(cache_index); \ | 877 new_object = isolate->partial_snapshot_cache()->at(cache_index); \ |
869 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ | 878 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ |
870 } else if (where == kExternalReference) { \ | 879 } else if (where == kExternalReference) { \ |
871 int skip = source_.GetInt(); \ | 880 int skip = source_.GetInt(); \ |
872 current = reinterpret_cast<Object**>( \ | 881 current = reinterpret_cast<Object**>( \ |
873 reinterpret_cast<Address>(current) + skip); \ | 882 reinterpret_cast<Address>(current) + skip); \ |
874 int reference_id = source_.GetInt(); \ | 883 int reference_id = source_.GetInt(); \ |
875 Address address = external_reference_table_->address(reference_id); \ | 884 Address address = external_reference_table_->address(reference_id); \ |
876 new_object = reinterpret_cast<Object*>(address); \ | 885 new_object = reinterpret_cast<Object*>(address); \ |
877 } else if (where == kBackref) { \ | 886 } else if (where == kAttachedReference) { \ |
878 emit_write_barrier = (space_number == NEW_SPACE); \ | 887 int index = source_.GetInt(); \ |
879 new_object = GetBackReferencedObject(data & kSpaceMask); \ | 888 DCHECK(deserializing_user_code() || index == kGlobalProxyReference); \ |
880 } else if (where == kBuiltin) { \ | 889 new_object = *attached_objects_[index]; \ |
| 890 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ |
| 891 } else { \ |
| 892 DCHECK(where == kBuiltin); \ |
881 DCHECK(deserializing_user_code()); \ | 893 DCHECK(deserializing_user_code()); \ |
882 int builtin_id = source_.GetInt(); \ | 894 int builtin_id = source_.GetInt(); \ |
883 DCHECK_LE(0, builtin_id); \ | 895 DCHECK_LE(0, builtin_id); \ |
884 DCHECK_LT(builtin_id, Builtins::builtin_count); \ | 896 DCHECK_LT(builtin_id, Builtins::builtin_count); \ |
885 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ | 897 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ |
886 new_object = isolate->builtins()->builtin(name); \ | 898 new_object = isolate->builtins()->builtin(name); \ |
887 emit_write_barrier = false; \ | 899 emit_write_barrier = false; \ |
888 } else if (where == kAttachedReference) { \ | |
889 int index = source_.GetInt(); \ | |
890 DCHECK(deserializing_user_code() || index == kGlobalProxyReference); \ | |
891 new_object = *attached_objects_[index]; \ | |
892 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ | |
893 } else { \ | |
894 DCHECK(where == kBackrefWithSkip); \ | |
895 int skip = source_.GetInt(); \ | |
896 current = reinterpret_cast<Object**>( \ | |
897 reinterpret_cast<Address>(current) + skip); \ | |
898 emit_write_barrier = (space_number == NEW_SPACE); \ | |
899 new_object = GetBackReferencedObject(data & kSpaceMask); \ | |
900 } \ | 900 } \ |
901 if (within == kInnerPointer) { \ | 901 if (within == kInnerPointer) { \ |
902 if (space_number != CODE_SPACE || new_object->IsCode()) { \ | 902 if (space_number != CODE_SPACE || new_object->IsCode()) { \ |
903 Code* new_code_object = reinterpret_cast<Code*>(new_object); \ | 903 Code* new_code_object = reinterpret_cast<Code*>(new_object); \ |
904 new_object = \ | 904 new_object = \ |
905 reinterpret_cast<Object*>(new_code_object->instruction_start()); \ | 905 reinterpret_cast<Object*>(new_code_object->instruction_start()); \ |
906 } else { \ | 906 } else { \ |
907 DCHECK(space_number == CODE_SPACE); \ | 907 DCHECK(space_number == CODE_SPACE); \ |
908 Cell* cell = Cell::cast(new_object); \ | 908 Cell* cell = Cell::cast(new_object); \ |
909 new_object = reinterpret_cast<Object*>(cell->ValueAddress()); \ | 909 new_object = reinterpret_cast<Object*>(cell->ValueAddress()); \ |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
952 case byte_code + 1: \ | 952 case byte_code + 1: \ |
953 case byte_code + 2: \ | 953 case byte_code + 2: \ |
954 case byte_code + 3: | 954 case byte_code + 3: |
955 | 955 |
956 #define SIXTEEN_CASES(byte_code) \ | 956 #define SIXTEEN_CASES(byte_code) \ |
957 FOUR_CASES(byte_code) \ | 957 FOUR_CASES(byte_code) \ |
958 FOUR_CASES(byte_code + 4) \ | 958 FOUR_CASES(byte_code + 4) \ |
959 FOUR_CASES(byte_code + 8) \ | 959 FOUR_CASES(byte_code + 8) \ |
960 FOUR_CASES(byte_code + 12) | 960 FOUR_CASES(byte_code + 12) |
961 | 961 |
962 #define COMMON_RAW_LENGTHS(f) \ | |
963 f(1) \ | |
964 f(2) \ | |
965 f(3) \ | |
966 f(4) \ | |
967 f(5) \ | |
968 f(6) \ | |
969 f(7) \ | |
970 f(8) \ | |
971 f(9) \ | |
972 f(10) \ | |
973 f(11) \ | |
974 f(12) \ | |
975 f(13) \ | |
976 f(14) \ | |
977 f(15) \ | |
978 f(16) \ | |
979 f(17) \ | |
980 f(18) \ | |
981 f(19) \ | |
982 f(20) \ | |
983 f(21) \ | |
984 f(22) \ | |
985 f(23) \ | |
986 f(24) \ | |
987 f(25) \ | |
988 f(26) \ | |
989 f(27) \ | |
990 f(28) \ | |
991 f(29) \ | |
992 f(30) \ | |
993 f(31) | |
994 | |
995 // We generate 15 cases and bodies that process special tags that combine | |
996 // the raw data tag and the length into one byte. | |
997 #define RAW_CASE(index) \ | |
998 case kRawData + index: { \ | |
999 byte* raw_data_out = reinterpret_cast<byte*>(current); \ | |
1000 source_.CopyRaw(raw_data_out, index* kPointerSize); \ | |
1001 current = reinterpret_cast<Object**>(raw_data_out + index * kPointerSize); \ | |
1002 break; \ | |
1003 } | |
1004 COMMON_RAW_LENGTHS(RAW_CASE) | |
1005 #undef RAW_CASE | |
1006 | |
1007 // Deserialize a chunk of raw data that doesn't have one of the popular | |
1008 // lengths. | |
1009 case kRawData: { | |
1010 int size = source_.GetInt(); | |
1011 byte* raw_data_out = reinterpret_cast<byte*>(current); | |
1012 source_.CopyRaw(raw_data_out, size); | |
1013 break; | |
1014 } | |
1015 | |
1016 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance) | |
1017 SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance + 16) { | |
1018 int root_id = RootArrayConstantFromByteCode(data); | |
1019 Object* object = isolate->heap()->roots_array_start()[root_id]; | |
1020 DCHECK(!isolate->heap()->InNewSpace(object)); | |
1021 UnalignedCopy(current++, &object); | |
1022 break; | |
1023 } | |
1024 | |
1025 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance) | |
1026 SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) { | |
1027 int root_id = RootArrayConstantFromByteCode(data); | |
1028 int skip = source_.GetInt(); | |
1029 current = reinterpret_cast<Object**>( | |
1030 reinterpret_cast<intptr_t>(current) + skip); | |
1031 Object* object = isolate->heap()->roots_array_start()[root_id]; | |
1032 DCHECK(!isolate->heap()->InNewSpace(object)); | |
1033 UnalignedCopy(current++, &object); | |
1034 break; | |
1035 } | |
1036 | |
1037 case kVariableRepeat: { | |
1038 int repeats = source_.GetInt(); | |
1039 Object* object = current[-1]; | |
1040 DCHECK(!isolate->heap()->InNewSpace(object)); | |
1041 for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object); | |
1042 break; | |
1043 } | |
1044 | |
1045 STATIC_ASSERT(kRootArrayNumberOfConstantEncodings == | |
1046 Heap::kOldSpaceRoots); | |
1047 STATIC_ASSERT(kMaxFixedRepeats == 15); | |
1048 FOUR_CASES(kFixedRepeat) | |
1049 FOUR_CASES(kFixedRepeat + 4) | |
1050 FOUR_CASES(kFixedRepeat + 8) | |
1051 case kFixedRepeat + 12: | |
1052 case kFixedRepeat + 13: | |
1053 case kFixedRepeat + 14: { | |
1054 int repeats = RepeatsForCode(data); | |
1055 Object* object; | |
1056 UnalignedCopy(&object, current - 1); | |
1057 DCHECK(!isolate->heap()->InNewSpace(object)); | |
1058 for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object); | |
1059 break; | |
1060 } | |
1061 | |
1062 // Deserialize a new object and write a pointer to it to the current | 962 // Deserialize a new object and write a pointer to it to the current |
1063 // object. | 963 // object. |
1064 ALL_SPACES(kNewObject, kPlain, kStartOfObject) | 964 ALL_SPACES(kNewObject, kPlain, kStartOfObject) |
1065 // Support for direct instruction pointers in functions. It's an inner | 965 // Support for direct instruction pointers in functions. It's an inner |
1066 // pointer because it points at the entry point, not at the start of the | 966 // pointer because it points at the entry point, not at the start of the |
1067 // code object. | 967 // code object. |
1068 CASE_STATEMENT(kNewObject, kPlain, kInnerPointer, CODE_SPACE) | 968 CASE_STATEMENT(kNewObject, kPlain, kInnerPointer, CODE_SPACE) |
1069 CASE_BODY(kNewObject, kPlain, kInnerPointer, CODE_SPACE) | 969 CASE_BODY(kNewObject, kPlain, kInnerPointer, CODE_SPACE) |
1070 // Deserialize a new code object and write a pointer to its first | 970 // Deserialize a new code object and write a pointer to its first |
1071 // instruction to the current code object. | 971 // instruction to the current code object. |
(...skipping 29 matching lines...) Expand all Loading... |
1101 CASE_BODY(kRootArray, kPlain, kStartOfObject, 0) | 1001 CASE_BODY(kRootArray, kPlain, kStartOfObject, 0) |
1102 #if defined(V8_TARGET_ARCH_MIPS) || V8_OOL_CONSTANT_POOL || \ | 1002 #if defined(V8_TARGET_ARCH_MIPS) || V8_OOL_CONSTANT_POOL || \ |
1103 defined(V8_TARGET_ARCH_MIPS64) || defined(V8_TARGET_ARCH_PPC) | 1003 defined(V8_TARGET_ARCH_MIPS64) || defined(V8_TARGET_ARCH_PPC) |
1104 // Find an object in the roots array and write a pointer to it to in code. | 1004 // Find an object in the roots array and write a pointer to it to in code. |
1105 CASE_STATEMENT(kRootArray, kFromCode, kStartOfObject, 0) | 1005 CASE_STATEMENT(kRootArray, kFromCode, kStartOfObject, 0) |
1106 CASE_BODY(kRootArray, kFromCode, kStartOfObject, 0) | 1006 CASE_BODY(kRootArray, kFromCode, kStartOfObject, 0) |
1107 #endif | 1007 #endif |
1108 // Find an object in the partial snapshots cache and write a pointer to it | 1008 // Find an object in the partial snapshots cache and write a pointer to it |
1109 // to the current object. | 1009 // to the current object. |
1110 CASE_STATEMENT(kPartialSnapshotCache, kPlain, kStartOfObject, 0) | 1010 CASE_STATEMENT(kPartialSnapshotCache, kPlain, kStartOfObject, 0) |
1111 CASE_BODY(kPartialSnapshotCache, | 1011 CASE_BODY(kPartialSnapshotCache, kPlain, kStartOfObject, 0) |
1112 kPlain, | |
1113 kStartOfObject, | |
1114 0) | |
1115 // Find an code entry in the partial snapshots cache and | 1012 // Find an code entry in the partial snapshots cache and |
1116 // write a pointer to it to the current object. | 1013 // write a pointer to it to the current object. |
1117 CASE_STATEMENT(kPartialSnapshotCache, kPlain, kInnerPointer, 0) | 1014 CASE_STATEMENT(kPartialSnapshotCache, kPlain, kInnerPointer, 0) |
1118 CASE_BODY(kPartialSnapshotCache, | 1015 CASE_BODY(kPartialSnapshotCache, kPlain, kInnerPointer, 0) |
1119 kPlain, | |
1120 kInnerPointer, | |
1121 0) | |
1122 // Find an external reference and write a pointer to it to the current | 1016 // Find an external reference and write a pointer to it to the current |
1123 // object. | 1017 // object. |
1124 CASE_STATEMENT(kExternalReference, kPlain, kStartOfObject, 0) | 1018 CASE_STATEMENT(kExternalReference, kPlain, kStartOfObject, 0) |
1125 CASE_BODY(kExternalReference, | 1019 CASE_BODY(kExternalReference, kPlain, kStartOfObject, 0) |
1126 kPlain, | |
1127 kStartOfObject, | |
1128 0) | |
1129 // Find an external reference and write a pointer to it in the current | 1020 // Find an external reference and write a pointer to it in the current |
1130 // code object. | 1021 // code object. |
1131 CASE_STATEMENT(kExternalReference, kFromCode, kStartOfObject, 0) | 1022 CASE_STATEMENT(kExternalReference, kFromCode, kStartOfObject, 0) |
1132 CASE_BODY(kExternalReference, | 1023 CASE_BODY(kExternalReference, kFromCode, kStartOfObject, 0) |
1133 kFromCode, | |
1134 kStartOfObject, | |
1135 0) | |
1136 // Find a builtin and write a pointer to it to the current object. | |
1137 CASE_STATEMENT(kBuiltin, kPlain, kStartOfObject, 0) | |
1138 CASE_BODY(kBuiltin, kPlain, kStartOfObject, 0) | |
1139 CASE_STATEMENT(kBuiltin, kPlain, kInnerPointer, 0) | |
1140 CASE_BODY(kBuiltin, kPlain, kInnerPointer, 0) | |
1141 CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0) | |
1142 CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0) | |
1143 // Find an object in the attached references and write a pointer to it to | 1024 // Find an object in the attached references and write a pointer to it to |
1144 // the current object. | 1025 // the current object. |
1145 CASE_STATEMENT(kAttachedReference, kPlain, kStartOfObject, 0) | 1026 CASE_STATEMENT(kAttachedReference, kPlain, kStartOfObject, 0) |
1146 CASE_BODY(kAttachedReference, kPlain, kStartOfObject, 0) | 1027 CASE_BODY(kAttachedReference, kPlain, kStartOfObject, 0) |
1147 CASE_STATEMENT(kAttachedReference, kPlain, kInnerPointer, 0) | 1028 CASE_STATEMENT(kAttachedReference, kPlain, kInnerPointer, 0) |
1148 CASE_BODY(kAttachedReference, kPlain, kInnerPointer, 0) | 1029 CASE_BODY(kAttachedReference, kPlain, kInnerPointer, 0) |
1149 CASE_STATEMENT(kAttachedReference, kFromCode, kInnerPointer, 0) | 1030 CASE_STATEMENT(kAttachedReference, kFromCode, kInnerPointer, 0) |
1150 CASE_BODY(kAttachedReference, kFromCode, kInnerPointer, 0) | 1031 CASE_BODY(kAttachedReference, kFromCode, kInnerPointer, 0) |
| 1032 // Find a builtin and write a pointer to it to the current object. |
| 1033 CASE_STATEMENT(kBuiltin, kPlain, kStartOfObject, 0) |
| 1034 CASE_BODY(kBuiltin, kPlain, kStartOfObject, 0) |
| 1035 CASE_STATEMENT(kBuiltin, kPlain, kInnerPointer, 0) |
| 1036 CASE_BODY(kBuiltin, kPlain, kInnerPointer, 0) |
| 1037 CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0) |
| 1038 CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0) |
1151 | 1039 |
1152 #undef CASE_STATEMENT | 1040 #undef CASE_STATEMENT |
1153 #undef CASE_BODY | 1041 #undef CASE_BODY |
1154 #undef ALL_SPACES | 1042 #undef ALL_SPACES |
1155 | 1043 |
1156 case kSkip: { | 1044 case kSkip: { |
1157 int size = source_.GetInt(); | 1045 int size = source_.GetInt(); |
1158 current = reinterpret_cast<Object**>( | 1046 current = reinterpret_cast<Object**>( |
1159 reinterpret_cast<intptr_t>(current) + size); | 1047 reinterpret_cast<intptr_t>(current) + size); |
1160 break; | 1048 break; |
1161 } | 1049 } |
1162 | 1050 |
1163 case kInternalReference: { | 1051 case kInternalReference: { |
1164 // Internal reference address is not encoded via skip, but by offset | 1052 // Internal reference address is not encoded via skip, but by offset |
1165 // from code entry. | 1053 // from code entry. |
1166 int pc_offset = source_.GetInt(); | 1054 int pc_offset = source_.GetInt(); |
1167 int target_offset = source_.GetInt(); | 1055 int target_offset = source_.GetInt(); |
1168 Code* code = | 1056 Code* code = |
1169 Code::cast(HeapObject::FromAddress(current_object_address)); | 1057 Code::cast(HeapObject::FromAddress(current_object_address)); |
1170 DCHECK(0 <= pc_offset && pc_offset <= code->instruction_size()); | 1058 DCHECK(0 <= pc_offset && pc_offset <= code->instruction_size()); |
1171 DCHECK(0 <= target_offset && target_offset <= code->instruction_size()); | 1059 DCHECK(0 <= target_offset && target_offset <= code->instruction_size()); |
1172 Address pc = code->entry() + pc_offset; | 1060 Address pc = code->entry() + pc_offset; |
1173 Address target = code->entry() + target_offset; | 1061 Address target = code->entry() + target_offset; |
1174 Assembler::deserialization_set_target_internal_reference_at(pc, target); | 1062 Assembler::deserialization_set_target_internal_reference_at(pc, target); |
1175 break; | 1063 break; |
1176 } | 1064 } |
1177 | 1065 |
1178 case kNativesStringResource: { | 1066 case kNop: |
1179 DCHECK(!isolate_->heap()->deserialization_complete()); | |
1180 int index = source_.Get(); | |
1181 Vector<const char> source_vector = Natives::GetScriptSource(index); | |
1182 NativesExternalStringResource* resource = | |
1183 new NativesExternalStringResource(source_vector.start(), | |
1184 source_vector.length()); | |
1185 Object* resource_obj = reinterpret_cast<Object*>(resource); | |
1186 UnalignedCopy(current++, &resource_obj); | |
1187 break; | 1067 break; |
1188 } | |
1189 | 1068 |
1190 case kNextChunk: { | 1069 case kNextChunk: { |
1191 int space = source_.Get(); | 1070 int space = source_.Get(); |
1192 DCHECK(space < kNumberOfPreallocatedSpaces); | 1071 DCHECK(space < kNumberOfPreallocatedSpaces); |
1193 int chunk_index = current_chunk_[space]; | 1072 int chunk_index = current_chunk_[space]; |
1194 const Heap::Reservation& reservation = reservations_[space]; | 1073 const Heap::Reservation& reservation = reservations_[space]; |
1195 // Make sure the current chunk is indeed exhausted. | 1074 // Make sure the current chunk is indeed exhausted. |
1196 CHECK_EQ(reservation[chunk_index].end, high_water_[space]); | 1075 CHECK_EQ(reservation[chunk_index].end, high_water_[space]); |
1197 // Move to next reserved chunk. | 1076 // Move to next reserved chunk. |
1198 chunk_index = ++current_chunk_[space]; | 1077 chunk_index = ++current_chunk_[space]; |
1199 CHECK_LT(chunk_index, reservation.length()); | 1078 CHECK_LT(chunk_index, reservation.length()); |
1200 high_water_[space] = reservation[chunk_index].start; | 1079 high_water_[space] = reservation[chunk_index].start; |
1201 break; | 1080 break; |
1202 } | 1081 } |
1203 | 1082 |
| 1083 case kSynchronize: |
| 1084 // If we get here then that indicates that you have a mismatch between |
| 1085 // the number of GC roots when serializing and deserializing. |
| 1086 CHECK(false); |
| 1087 break; |
| 1088 |
| 1089 case kNativesStringResource: { |
| 1090 DCHECK(!isolate_->heap()->deserialization_complete()); |
| 1091 int index = source_.Get(); |
| 1092 Vector<const char> source_vector = Natives::GetScriptSource(index); |
| 1093 NativesExternalStringResource* resource = |
| 1094 new NativesExternalStringResource(source_vector.start(), |
| 1095 source_vector.length()); |
| 1096 Object* resource_obj = reinterpret_cast<Object*>(resource); |
| 1097 UnalignedCopy(current++, &resource_obj); |
| 1098 break; |
| 1099 } |
| 1100 |
| 1101 // Deserialize raw data of variable length. |
| 1102 case kVariableRawData: { |
| 1103 int size_in_bytes = source_.GetInt(); |
| 1104 byte* raw_data_out = reinterpret_cast<byte*>(current); |
| 1105 source_.CopyRaw(raw_data_out, size_in_bytes); |
| 1106 break; |
| 1107 } |
| 1108 |
| 1109 case kVariableRepeat: { |
| 1110 int repeats = source_.GetInt(); |
| 1111 Object* object = current[-1]; |
| 1112 DCHECK(!isolate->heap()->InNewSpace(object)); |
| 1113 for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object); |
| 1114 break; |
| 1115 } |
| 1116 |
| 1117 STATIC_ASSERT(kNumberOfRootArrayConstants == Heap::kOldSpaceRoots); |
| 1118 STATIC_ASSERT(kNumberOfRootArrayConstants == 32); |
| 1119 SIXTEEN_CASES(kRootArrayConstantsWithSkip) |
| 1120 SIXTEEN_CASES(kRootArrayConstantsWithSkip + 16) { |
| 1121 int skip = source_.GetInt(); |
| 1122 current = reinterpret_cast<Object**>( |
| 1123 reinterpret_cast<intptr_t>(current) + skip); |
| 1124 // Fall through. |
| 1125 } |
| 1126 |
| 1127 SIXTEEN_CASES(kRootArrayConstants) |
| 1128 SIXTEEN_CASES(kRootArrayConstants + 16) { |
| 1129 int root_id = data & kRootArrayConstantsMask; |
| 1130 Object* object = isolate->heap()->roots_array_start()[root_id]; |
| 1131 DCHECK(!isolate->heap()->InNewSpace(object)); |
| 1132 UnalignedCopy(current++, &object); |
| 1133 break; |
| 1134 } |
| 1135 |
| 1136 STATIC_ASSERT(kNumberOfHotObjects == 8); |
1204 FOUR_CASES(kHotObjectWithSkip) | 1137 FOUR_CASES(kHotObjectWithSkip) |
1205 FOUR_CASES(kHotObjectWithSkip + 4) { | 1138 FOUR_CASES(kHotObjectWithSkip + 4) { |
1206 int skip = source_.GetInt(); | 1139 int skip = source_.GetInt(); |
1207 current = reinterpret_cast<Object**>( | 1140 current = reinterpret_cast<Object**>( |
1208 reinterpret_cast<Address>(current) + skip); | 1141 reinterpret_cast<Address>(current) + skip); |
1209 // Fall through. | 1142 // Fall through. |
1210 } | 1143 } |
| 1144 |
1211 FOUR_CASES(kHotObject) | 1145 FOUR_CASES(kHotObject) |
1212 FOUR_CASES(kHotObject + 4) { | 1146 FOUR_CASES(kHotObject + 4) { |
1213 int index = data & kHotObjectIndexMask; | 1147 int index = data & kHotObjectMask; |
1214 Object* hot_object = hot_objects_.Get(index); | 1148 Object* hot_object = hot_objects_.Get(index); |
1215 UnalignedCopy(current, &hot_object); | 1149 UnalignedCopy(current, &hot_object); |
1216 if (write_barrier_needed && isolate->heap()->InNewSpace(hot_object)) { | 1150 if (write_barrier_needed && isolate->heap()->InNewSpace(hot_object)) { |
1217 Address current_address = reinterpret_cast<Address>(current); | 1151 Address current_address = reinterpret_cast<Address>(current); |
1218 isolate->heap()->RecordWrite( | 1152 isolate->heap()->RecordWrite( |
1219 current_object_address, | 1153 current_object_address, |
1220 static_cast<int>(current_address - current_object_address)); | 1154 static_cast<int>(current_address - current_object_address)); |
1221 } | 1155 } |
1222 current++; | 1156 current++; |
1223 break; | 1157 break; |
1224 } | 1158 } |
1225 | 1159 |
1226 case kSynchronize: { | 1160 // Deserialize raw data of fixed length from 1 to 32 words. |
1227 // If we get here then that indicates that you have a mismatch between | 1161 STATIC_ASSERT(kNumberOfFixedRawData == 32); |
1228 // the number of GC roots when serializing and deserializing. | 1162 SIXTEEN_CASES(kFixedRawData) |
1229 CHECK(false); | 1163 SIXTEEN_CASES(kFixedRawData + 16) { |
| 1164 byte* raw_data_out = reinterpret_cast<byte*>(current); |
| 1165 int size_in_bytes = (data - kFixedRawDataStart) << kPointerSizeLog2; |
| 1166 source_.CopyRaw(raw_data_out, size_in_bytes); |
| 1167 current = reinterpret_cast<Object**>(raw_data_out + size_in_bytes); |
| 1168 break; |
1230 } | 1169 } |
1231 | 1170 |
| 1171 STATIC_ASSERT(kNumberOfFixedRepeat == 16); |
| 1172 SIXTEEN_CASES(kFixedRepeat) { |
| 1173 int repeats = data - kFixedRepeatStart; |
| 1174 Object* object; |
| 1175 UnalignedCopy(&object, current - 1); |
| 1176 DCHECK(!isolate->heap()->InNewSpace(object)); |
| 1177 for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object); |
| 1178 break; |
| 1179 } |
| 1180 |
| 1181 #undef SIXTEEN_CASES |
| 1182 #undef FOUR_CASES |
| 1183 |
1232 default: | 1184 default: |
1233 CHECK(false); | 1185 CHECK(false); |
1234 } | 1186 } |
1235 } | 1187 } |
1236 CHECK_EQ(limit, current); | 1188 CHECK_EQ(limit, current); |
1237 } | 1189 } |
1238 | 1190 |
1239 | 1191 |
1240 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) | 1192 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) |
1241 : isolate_(isolate), | 1193 : isolate_(isolate), |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1439 } | 1391 } |
1440 #endif // DEBUG | 1392 #endif // DEBUG |
1441 | 1393 |
1442 | 1394 |
1443 bool Serializer::SerializeKnownObject(HeapObject* obj, HowToCode how_to_code, | 1395 bool Serializer::SerializeKnownObject(HeapObject* obj, HowToCode how_to_code, |
1444 WhereToPoint where_to_point, int skip) { | 1396 WhereToPoint where_to_point, int skip) { |
1445 if (how_to_code == kPlain && where_to_point == kStartOfObject) { | 1397 if (how_to_code == kPlain && where_to_point == kStartOfObject) { |
1446 // Encode a reference to a hot object by its index in the working set. | 1398 // Encode a reference to a hot object by its index in the working set. |
1447 int index = hot_objects_.Find(obj); | 1399 int index = hot_objects_.Find(obj); |
1448 if (index != HotObjectsList::kNotFound) { | 1400 if (index != HotObjectsList::kNotFound) { |
1449 DCHECK(index >= 0 && index <= kMaxHotObjectIndex); | 1401 DCHECK(index >= 0 && index < kNumberOfHotObjects); |
1450 if (FLAG_trace_serializer) { | 1402 if (FLAG_trace_serializer) { |
1451 PrintF(" Encoding hot object %d:", index); | 1403 PrintF(" Encoding hot object %d:", index); |
1452 obj->ShortPrint(); | 1404 obj->ShortPrint(); |
1453 PrintF("\n"); | 1405 PrintF("\n"); |
1454 } | 1406 } |
1455 if (skip != 0) { | 1407 if (skip != 0) { |
1456 sink_->Put(kHotObjectWithSkip + index, "HotObjectWithSkip"); | 1408 sink_->Put(kHotObjectWithSkip + index, "HotObjectWithSkip"); |
1457 sink_->PutInt(skip, "HotObjectSkipDistance"); | 1409 sink_->PutInt(skip, "HotObjectSkipDistance"); |
1458 } else { | 1410 } else { |
1459 sink_->Put(kHotObject + index, "HotObject"); | 1411 sink_->Put(kHotObject + index, "HotObject"); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1550 HeapObject* object, | 1502 HeapObject* object, |
1551 SerializerDeserializer::HowToCode how_to_code, | 1503 SerializerDeserializer::HowToCode how_to_code, |
1552 SerializerDeserializer::WhereToPoint where_to_point, | 1504 SerializerDeserializer::WhereToPoint where_to_point, |
1553 int skip) { | 1505 int skip) { |
1554 if (FLAG_trace_serializer) { | 1506 if (FLAG_trace_serializer) { |
1555 PrintF(" Encoding root %d:", root_index); | 1507 PrintF(" Encoding root %d:", root_index); |
1556 object->ShortPrint(); | 1508 object->ShortPrint(); |
1557 PrintF("\n"); | 1509 PrintF("\n"); |
1558 } | 1510 } |
1559 | 1511 |
1560 if (how_to_code == kPlain && | 1512 if (how_to_code == kPlain && where_to_point == kStartOfObject && |
1561 where_to_point == kStartOfObject && | 1513 root_index < kNumberOfRootArrayConstants && |
1562 root_index < kRootArrayNumberOfConstantEncodings && | |
1563 !isolate()->heap()->InNewSpace(object)) { | 1514 !isolate()->heap()->InNewSpace(object)) { |
1564 if (skip == 0) { | 1515 if (skip == 0) { |
1565 sink_->Put(kRootArrayConstants + kNoSkipDistance + root_index, | 1516 sink_->Put(kRootArrayConstants + root_index, "RootConstant"); |
1566 "RootConstant"); | |
1567 } else { | 1517 } else { |
1568 sink_->Put(kRootArrayConstants + kHasSkipDistance + root_index, | 1518 sink_->Put(kRootArrayConstantsWithSkip + root_index, "RootConstant"); |
1569 "RootConstant"); | |
1570 sink_->PutInt(skip, "SkipInPutRoot"); | 1519 sink_->PutInt(skip, "SkipInPutRoot"); |
1571 } | 1520 } |
1572 } else { | 1521 } else { |
1573 FlushSkip(skip); | 1522 FlushSkip(skip); |
1574 sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization"); | 1523 sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization"); |
1575 sink_->PutInt(root_index, "root_index"); | 1524 sink_->PutInt(root_index, "root_index"); |
1576 } | 1525 } |
1577 } | 1526 } |
1578 | 1527 |
1579 | 1528 |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1710 | 1659 |
1711 AllocationSpace space = (allocation_size > Page::kMaxRegularHeapObjectSize) | 1660 AllocationSpace space = (allocation_size > Page::kMaxRegularHeapObjectSize) |
1712 ? LO_SPACE | 1661 ? LO_SPACE |
1713 : OLD_SPACE; | 1662 : OLD_SPACE; |
1714 SerializePrologue(space, allocation_size, map); | 1663 SerializePrologue(space, allocation_size, map); |
1715 | 1664 |
1716 // Output the rest of the imaginary string. | 1665 // Output the rest of the imaginary string. |
1717 int bytes_to_output = allocation_size - HeapObject::kHeaderSize; | 1666 int bytes_to_output = allocation_size - HeapObject::kHeaderSize; |
1718 | 1667 |
1719 // Output raw data header. Do not bother with common raw length cases here. | 1668 // Output raw data header. Do not bother with common raw length cases here. |
1720 sink_->Put(kRawData, "RawDataForString"); | 1669 sink_->Put(kVariableRawData, "RawDataForString"); |
1721 sink_->PutInt(bytes_to_output, "length"); | 1670 sink_->PutInt(bytes_to_output, "length"); |
1722 | 1671 |
1723 // Serialize string header (except for map). | 1672 // Serialize string header (except for map). |
1724 Address string_start = string->address(); | 1673 Address string_start = string->address(); |
1725 for (int i = HeapObject::kHeaderSize; i < SeqString::kHeaderSize; i++) { | 1674 for (int i = HeapObject::kHeaderSize; i < SeqString::kHeaderSize; i++) { |
1726 sink_->PutSection(string_start[i], "StringHeader"); | 1675 sink_->PutSection(string_start[i], "StringHeader"); |
1727 } | 1676 } |
1728 | 1677 |
1729 // Serialize string content. | 1678 // Serialize string content. |
1730 sink_->PutRaw(resource, content_size, "StringContent"); | 1679 sink_->PutRaw(resource, content_size, "StringContent"); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1801 Heap::RootIsImmortalImmovable(root_index) && | 1750 Heap::RootIsImmortalImmovable(root_index) && |
1802 current_contents == current[-1]) { | 1751 current_contents == current[-1]) { |
1803 DCHECK(!serializer_->isolate()->heap()->InNewSpace(current_contents)); | 1752 DCHECK(!serializer_->isolate()->heap()->InNewSpace(current_contents)); |
1804 int repeat_count = 1; | 1753 int repeat_count = 1; |
1805 while (¤t[repeat_count] < end - 1 && | 1754 while (¤t[repeat_count] < end - 1 && |
1806 current[repeat_count] == current_contents) { | 1755 current[repeat_count] == current_contents) { |
1807 repeat_count++; | 1756 repeat_count++; |
1808 } | 1757 } |
1809 current += repeat_count; | 1758 current += repeat_count; |
1810 bytes_processed_so_far_ += repeat_count * kPointerSize; | 1759 bytes_processed_so_far_ += repeat_count * kPointerSize; |
1811 if (repeat_count > kMaxFixedRepeats) { | 1760 if (repeat_count > kNumberOfFixedRepeat) { |
1812 sink_->Put(kVariableRepeat, "SerializeRepeats"); | 1761 sink_->Put(kVariableRepeat, "VariableRepeat"); |
1813 sink_->PutInt(repeat_count, "SerializeRepeats"); | 1762 sink_->PutInt(repeat_count, "repeat count"); |
1814 } else { | 1763 } else { |
1815 sink_->Put(CodeForRepeats(repeat_count), "SerializeRepeats"); | 1764 sink_->Put(kFixedRepeatStart + repeat_count, "FixedRepeat"); |
1816 } | 1765 } |
1817 } else { | 1766 } else { |
1818 serializer_->SerializeObject( | 1767 serializer_->SerializeObject( |
1819 current_contents, kPlain, kStartOfObject, 0); | 1768 current_contents, kPlain, kStartOfObject, 0); |
1820 bytes_processed_so_far_ += kPointerSize; | 1769 bytes_processed_so_far_ += kPointerSize; |
1821 current++; | 1770 current++; |
1822 } | 1771 } |
1823 } | 1772 } |
1824 } | 1773 } |
1825 } | 1774 } |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1990 // locations in a non-ascending order. Luckily that doesn't happen. | 1939 // locations in a non-ascending order. Luckily that doesn't happen. |
1991 DCHECK(to_skip >= 0); | 1940 DCHECK(to_skip >= 0); |
1992 bool outputting_code = false; | 1941 bool outputting_code = false; |
1993 if (to_skip != 0 && is_code_object_ && !code_has_been_output_) { | 1942 if (to_skip != 0 && is_code_object_ && !code_has_been_output_) { |
1994 // Output the code all at once and fix later. | 1943 // Output the code all at once and fix later. |
1995 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_; | 1944 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_; |
1996 outputting_code = true; | 1945 outputting_code = true; |
1997 code_has_been_output_ = true; | 1946 code_has_been_output_ = true; |
1998 } | 1947 } |
1999 if (bytes_to_output != 0 && (!is_code_object_ || outputting_code)) { | 1948 if (bytes_to_output != 0 && (!is_code_object_ || outputting_code)) { |
2000 #define RAW_CASE(index) \ | 1949 if (!outputting_code && bytes_to_output == to_skip && |
2001 if (!outputting_code && bytes_to_output == index * kPointerSize && \ | 1950 IsAligned(bytes_to_output, kPointerAlignment) && |
2002 index * kPointerSize == to_skip) { \ | 1951 bytes_to_output <= kNumberOfFixedRawData * kPointerSize) { |
2003 sink_->PutSection(kRawData + index, "RawDataFixed"); \ | 1952 int size_in_words = bytes_to_output >> kPointerSizeLog2; |
2004 to_skip = 0; /* This insn already skips. */ \ | 1953 sink_->PutSection(kFixedRawDataStart + size_in_words, "FixedRawData"); |
2005 } else /* NOLINT */ | 1954 to_skip = 0; // This instruction includes skip. |
2006 COMMON_RAW_LENGTHS(RAW_CASE) | 1955 } else { |
2007 #undef RAW_CASE | |
2008 { /* NOLINT */ | |
2009 // We always end up here if we are outputting the code of a code object. | 1956 // We always end up here if we are outputting the code of a code object. |
2010 sink_->Put(kRawData, "RawData"); | 1957 sink_->Put(kVariableRawData, "VariableRawData"); |
2011 sink_->PutInt(bytes_to_output, "length"); | 1958 sink_->PutInt(bytes_to_output, "length"); |
2012 } | 1959 } |
2013 | 1960 |
2014 if (is_code_object_) object_start = PrepareCode(); | 1961 if (is_code_object_) object_start = PrepareCode(); |
2015 | 1962 |
2016 const char* description = is_code_object_ ? "Code" : "Byte"; | 1963 const char* description = is_code_object_ ? "Code" : "Byte"; |
2017 #ifdef MEMORY_SANITIZER | 1964 #ifdef MEMORY_SANITIZER |
2018 // Object sizes are usually rounded up with uninitialized padding space. | 1965 // Object sizes are usually rounded up with uninitialized padding space. |
2019 MSAN_MEMORY_IS_INITIALIZED(object_start + base, bytes_to_output); | 1966 MSAN_MEMORY_IS_INITIALIZED(object_start + base, bytes_to_output); |
2020 #endif // MEMORY_SANITIZER | 1967 #endif // MEMORY_SANITIZER |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2561 DisallowHeapAllocation no_gc; | 2508 DisallowHeapAllocation no_gc; |
2562 SerializedCodeData* scd = new SerializedCodeData(cached_data); | 2509 SerializedCodeData* scd = new SerializedCodeData(cached_data); |
2563 SanityCheckResult r = scd->SanityCheck(isolate, source); | 2510 SanityCheckResult r = scd->SanityCheck(isolate, source); |
2564 if (r == CHECK_SUCCESS) return scd; | 2511 if (r == CHECK_SUCCESS) return scd; |
2565 cached_data->Reject(); | 2512 cached_data->Reject(); |
2566 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); | 2513 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); |
2567 delete scd; | 2514 delete scd; |
2568 return NULL; | 2515 return NULL; |
2569 } | 2516 } |
2570 } } // namespace v8::internal | 2517 } } // namespace v8::internal |
OLD | NEW |