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

Side by Side Diff: src/serialize.cc

Issue 1018263002: Serializer: clean up opcodes. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/serialize.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/base/platform/platform.h" 9 #include "src/base/platform/platform.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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 (&current[repeat_count] < end - 1 && 1754 while (&current[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
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
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
OLDNEW
« no previous file with comments | « src/serialize.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698