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

Side by Side Diff: src/serialize.cc

Issue 766893002: Serializer: cache recent back references for shorter encoding. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: addressed comments Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/serialize.h ('k') | src/snapshot-source-sink.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/base/platform/platform.h" 9 #include "src/base/platform/platform.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 StringTableInsertionKey key(string); 787 StringTableInsertionKey key(string);
788 String* canonical = *StringTable::LookupKey(isolate_, &key); 788 String* canonical = *StringTable::LookupKey(isolate_, &key);
789 string->SetForwardedInternalizedString(canonical); 789 string->SetForwardedInternalizedString(canonical);
790 return canonical; 790 return canonical;
791 } 791 }
792 } 792 }
793 return obj; 793 return obj;
794 } 794 }
795 795
796 796
797 Object* Deserializer::ProcessBackRefInSerializedCode(Object* obj) { 797 HeapObject* Deserializer::GetBackReferencedObject(int space) {
798 if (obj->IsInternalizedString()) { 798 HeapObject* obj;
799 return String::cast(obj)->GetForwardedInternalizedString(); 799 if (space == LO_SPACE) {
800 uint32_t index = source_->GetInt();
801 obj = deserialized_large_objects_[index];
802 } else {
803 BackReference back_reference(source_->GetInt());
804 DCHECK(space < kNumberOfPreallocatedSpaces);
805 uint32_t chunk_index = back_reference.chunk_index();
806 DCHECK_LE(chunk_index, current_chunk_[space]);
807 uint32_t chunk_offset = back_reference.chunk_offset();
808 obj = HeapObject::FromAddress(reservations_[space][chunk_index].start +
809 chunk_offset);
800 } 810 }
811 if (deserializing_user_code() && obj->IsInternalizedString()) {
812 obj = String::cast(obj)->GetForwardedInternalizedString();
813 }
814 hot_objects_.Add(obj);
801 return obj; 815 return obj;
802 } 816 }
803 817
804 818
805 // This routine writes the new object into the pointer provided and then 819 // 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. 820 // 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 821 // 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 822 // 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. 823 // 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) { 824 void Deserializer::ReadObject(int space_number, Object** write_back) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 // Write barrier support costs around 1% in startup time. In fact there 911 // 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, 912 // are no new space objects in current boot snapshots, so it's not needed,
899 // but that may change. 913 // but that may change.
900 bool write_barrier_needed = (current_object_address != NULL && 914 bool write_barrier_needed = (current_object_address != NULL &&
901 source_space != NEW_SPACE && 915 source_space != NEW_SPACE &&
902 source_space != CELL_SPACE && 916 source_space != CELL_SPACE &&
903 source_space != PROPERTY_CELL_SPACE && 917 source_space != PROPERTY_CELL_SPACE &&
904 source_space != CODE_SPACE && 918 source_space != CODE_SPACE &&
905 source_space != OLD_DATA_SPACE); 919 source_space != OLD_DATA_SPACE);
906 while (current < limit) { 920 while (current < limit) {
907 int data = source_->Get(); 921 byte data = source_->Get();
908 switch (data) { 922 switch (data) {
909 #define CASE_STATEMENT(where, how, within, space_number) \ 923 #define CASE_STATEMENT(where, how, within, space_number) \
910 case where + how + within + space_number: \ 924 case where + how + within + space_number: \
911 STATIC_ASSERT((where & ~kPointedToMask) == 0); \ 925 STATIC_ASSERT((where & ~kPointedToMask) == 0); \
912 STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \ 926 STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \
913 STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \ 927 STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \
914 STATIC_ASSERT((space_number & ~kSpaceMask) == 0); 928 STATIC_ASSERT((space_number & ~kSpaceMask) == 0);
915 929
916 #define CASE_BODY(where, how, within, space_number_if_any) \ 930 #define CASE_BODY(where, how, within, space_number_if_any) \
917 { \ 931 { \
(...skipping 20 matching lines...) Expand all
938 } else if (where == kExternalReference) { \ 952 } else if (where == kExternalReference) { \
939 int skip = source_->GetInt(); \ 953 int skip = source_->GetInt(); \
940 current = reinterpret_cast<Object**>( \ 954 current = reinterpret_cast<Object**>( \
941 reinterpret_cast<Address>(current) + skip); \ 955 reinterpret_cast<Address>(current) + skip); \
942 int reference_id = source_->GetInt(); \ 956 int reference_id = source_->GetInt(); \
943 Address address = external_reference_decoder_->Decode(reference_id); \ 957 Address address = external_reference_decoder_->Decode(reference_id); \
944 new_object = reinterpret_cast<Object*>(address); \ 958 new_object = reinterpret_cast<Object*>(address); \
945 } else if (where == kBackref) { \ 959 } else if (where == kBackref) { \
946 emit_write_barrier = (space_number == NEW_SPACE); \ 960 emit_write_barrier = (space_number == NEW_SPACE); \
947 new_object = GetBackReferencedObject(data & kSpaceMask); \ 961 new_object = GetBackReferencedObject(data & kSpaceMask); \
948 if (deserializing_user_code()) { \
949 new_object = ProcessBackRefInSerializedCode(new_object); \
950 } \
951 } else if (where == kBuiltin) { \ 962 } else if (where == kBuiltin) { \
952 DCHECK(deserializing_user_code()); \ 963 DCHECK(deserializing_user_code()); \
953 int builtin_id = source_->GetInt(); \ 964 int builtin_id = source_->GetInt(); \
954 DCHECK_LE(0, builtin_id); \ 965 DCHECK_LE(0, builtin_id); \
955 DCHECK_LT(builtin_id, Builtins::builtin_count); \ 966 DCHECK_LT(builtin_id, Builtins::builtin_count); \
956 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \ 967 Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \
957 new_object = isolate->builtins()->builtin(name); \ 968 new_object = isolate->builtins()->builtin(name); \
958 emit_write_barrier = false; \ 969 emit_write_barrier = false; \
959 } else if (where == kAttachedReference) { \ 970 } else if (where == kAttachedReference) { \
960 DCHECK(deserializing_user_code()); \ 971 DCHECK(deserializing_user_code()); \
961 int index = source_->GetInt(); \ 972 int index = source_->GetInt(); \
962 new_object = *attached_objects_->at(index); \ 973 new_object = *attached_objects_->at(index); \
963 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ 974 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
964 } else { \ 975 } else { \
965 DCHECK(where == kBackrefWithSkip); \ 976 DCHECK(where == kBackrefWithSkip); \
966 int skip = source_->GetInt(); \ 977 int skip = source_->GetInt(); \
967 current = reinterpret_cast<Object**>( \ 978 current = reinterpret_cast<Object**>( \
968 reinterpret_cast<Address>(current) + skip); \ 979 reinterpret_cast<Address>(current) + skip); \
969 emit_write_barrier = (space_number == NEW_SPACE); \ 980 emit_write_barrier = (space_number == NEW_SPACE); \
970 new_object = GetBackReferencedObject(data & kSpaceMask); \ 981 new_object = GetBackReferencedObject(data & kSpaceMask); \
971 if (deserializing_user_code()) { \
972 new_object = ProcessBackRefInSerializedCode(new_object); \
973 } \
974 } \ 982 } \
975 if (within == kInnerPointer) { \ 983 if (within == kInnerPointer) { \
976 if (space_number != CODE_SPACE || new_object->IsCode()) { \ 984 if (space_number != CODE_SPACE || new_object->IsCode()) { \
977 Code* new_code_object = reinterpret_cast<Code*>(new_object); \ 985 Code* new_code_object = reinterpret_cast<Code*>(new_object); \
978 new_object = \ 986 new_object = \
979 reinterpret_cast<Object*>(new_code_object->instruction_start()); \ 987 reinterpret_cast<Object*>(new_code_object->instruction_start()); \
980 } else { \ 988 } else { \
981 DCHECK(space_number == CODE_SPACE); \ 989 DCHECK(space_number == CODE_SPACE); \
982 Cell* cell = Cell::cast(new_object); \ 990 Cell* cell = Cell::cast(new_object); \
983 new_object = reinterpret_cast<Object*>(cell->ValueAddress()); \ 991 new_object = reinterpret_cast<Object*>(cell->ValueAddress()); \
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 kVariableRepeat: {
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(kMaxFixedRepeats == 15);
1126 case kConstantRepeat: 1134 FOUR_CASES(kFixedRepeat)
1127 FOUR_CASES(kConstantRepeat + 1) 1135 FOUR_CASES(kFixedRepeat + 4)
1128 FOUR_CASES(kConstantRepeat + 5) 1136 FOUR_CASES(kFixedRepeat + 8)
1129 FOUR_CASES(kConstantRepeat + 9) { 1137 case kFixedRepeat + 12:
1138 case kFixedRepeat + 13:
1139 case kFixedRepeat + 14: {
1130 int repeats = RepeatsForCode(data); 1140 int repeats = RepeatsForCode(data);
1131 Object* object = current[-1]; 1141 Object* object = current[-1];
1132 DCHECK(!isolate->heap()->InNewSpace(object)); 1142 DCHECK(!isolate->heap()->InNewSpace(object));
1133 for (int i = 0; i < repeats; i++) current[i] = object; 1143 for (int i = 0; i < repeats; i++) current[i] = object;
1134 current += repeats; 1144 current += repeats;
1135 break; 1145 break;
1136 } 1146 }
1137 1147
1138 // Deserialize a new object and write a pointer to it to the current 1148 // Deserialize a new object and write a pointer to it to the current
1139 // object. 1149 // object.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 const Heap::Reservation& reservation = reservations_[space]; 1264 const Heap::Reservation& reservation = reservations_[space];
1255 // Make sure the current chunk is indeed exhausted. 1265 // Make sure the current chunk is indeed exhausted.
1256 CHECK_EQ(reservation[chunk_index].end, high_water_[space]); 1266 CHECK_EQ(reservation[chunk_index].end, high_water_[space]);
1257 // Move to next reserved chunk. 1267 // Move to next reserved chunk.
1258 chunk_index = ++current_chunk_[space]; 1268 chunk_index = ++current_chunk_[space];
1259 DCHECK_LT(chunk_index, reservation.length()); 1269 DCHECK_LT(chunk_index, reservation.length());
1260 high_water_[space] = reservation[chunk_index].start; 1270 high_water_[space] = reservation[chunk_index].start;
1261 break; 1271 break;
1262 } 1272 }
1263 1273
1274 FOUR_CASES(kHotObjectWithSkip)
1275 FOUR_CASES(kHotObjectWithSkip + 4) {
1276 int skip = source_->GetInt();
1277 current = reinterpret_cast<Object**>(
1278 reinterpret_cast<Address>(current) + skip);
1279 // Fall through.
1280 }
1281 FOUR_CASES(kHotObject)
1282 FOUR_CASES(kHotObject + 4) {
1283 int index = data & kHotObjectIndexMask;
1284 *current = hot_objects_.Get(index);
1285 if (write_barrier_needed && isolate->heap()->InNewSpace(*current)) {
1286 Address current_address = reinterpret_cast<Address>(current);
1287 isolate->heap()->RecordWrite(
1288 current_object_address,
1289 static_cast<int>(current_address - current_object_address));
1290 }
1291 current++;
1292 break;
1293 }
1294
1264 case kSynchronize: { 1295 case kSynchronize: {
1265 // If we get here then that indicates that you have a mismatch between 1296 // If we get here then that indicates that you have a mismatch between
1266 // the number of GC roots when serializing and deserializing. 1297 // the number of GC roots when serializing and deserializing.
1267 UNREACHABLE(); 1298 UNREACHABLE();
1268 } 1299 }
1269 1300
1270 default: 1301 default:
1271 UNREACHABLE(); 1302 UNREACHABLE();
1272 } 1303 }
1273 } 1304 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1317 void StartupSerializer::VisitPointers(Object** start, Object** end) { 1348 void StartupSerializer::VisitPointers(Object** start, Object** end) {
1318 for (Object** current = start; current < end; current++) { 1349 for (Object** current = start; current < end; current++) {
1319 if (start == isolate()->heap()->roots_array_start()) { 1350 if (start == isolate()->heap()->roots_array_start()) {
1320 root_index_wave_front_ = 1351 root_index_wave_front_ =
1321 Max(root_index_wave_front_, static_cast<intptr_t>(current - start)); 1352 Max(root_index_wave_front_, static_cast<intptr_t>(current - start));
1322 } 1353 }
1323 if (ShouldBeSkipped(current)) { 1354 if (ShouldBeSkipped(current)) {
1324 sink_->Put(kSkip, "Skip"); 1355 sink_->Put(kSkip, "Skip");
1325 sink_->PutInt(kPointerSize, "SkipOneWord"); 1356 sink_->PutInt(kPointerSize, "SkipOneWord");
1326 } else if ((*current)->IsSmi()) { 1357 } else if ((*current)->IsSmi()) {
1327 sink_->Put(kRawData + 1, "Smi"); 1358 sink_->Put(kOnePointerRawData, "Smi");
1328 for (int i = 0; i < kPointerSize; i++) { 1359 for (int i = 0; i < kPointerSize; i++) {
1329 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); 1360 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte");
1330 } 1361 }
1331 } else { 1362 } else {
1332 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0); 1363 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0);
1333 } 1364 }
1334 } 1365 }
1335 } 1366 }
1336 1367
1337 1368
1338 void PartialSerializer::Serialize(Object** object) { 1369 void PartialSerializer::Serialize(Object** object) {
1339 this->VisitPointer(object); 1370 this->VisitPointer(object);
1340 Pad(); 1371 Pad();
1341 } 1372 }
1342 1373
1343 1374
1344 bool Serializer::ShouldBeSkipped(Object** current) { 1375 bool Serializer::ShouldBeSkipped(Object** current) {
1345 Object** roots = isolate()->heap()->roots_array_start(); 1376 Object** roots = isolate()->heap()->roots_array_start();
1346 return current == &roots[Heap::kStoreBufferTopRootIndex] 1377 return current == &roots[Heap::kStoreBufferTopRootIndex]
1347 || current == &roots[Heap::kStackLimitRootIndex] 1378 || current == &roots[Heap::kStackLimitRootIndex]
1348 || current == &roots[Heap::kRealStackLimitRootIndex]; 1379 || current == &roots[Heap::kRealStackLimitRootIndex];
1349 } 1380 }
1350 1381
1351 1382
1352 void Serializer::VisitPointers(Object** start, Object** end) { 1383 void Serializer::VisitPointers(Object** start, Object** end) {
1353 for (Object** current = start; current < end; current++) { 1384 for (Object** current = start; current < end; current++) {
1354 if ((*current)->IsSmi()) { 1385 if ((*current)->IsSmi()) {
1355 sink_->Put(kRawData + 1, "Smi"); 1386 sink_->Put(kOnePointerRawData, "Smi");
1356 for (int i = 0; i < kPointerSize; i++) { 1387 for (int i = 0; i < kPointerSize; i++) {
1357 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); 1388 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte");
1358 } 1389 }
1359 } else { 1390 } else {
1360 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0); 1391 SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0);
1361 } 1392 }
1362 } 1393 }
1363 } 1394 }
1364 1395
1365 1396
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 int length = isolate->serialize_partial_snapshot_cache_length(); 1450 int length = isolate->serialize_partial_snapshot_cache_length();
1420 isolate->PushToPartialSnapshotCache(heap_object); 1451 isolate->PushToPartialSnapshotCache(heap_object);
1421 startup_serializer_->VisitPointer(reinterpret_cast<Object**>(&heap_object)); 1452 startup_serializer_->VisitPointer(reinterpret_cast<Object**>(&heap_object));
1422 // We don't recurse from the startup snapshot generator into the partial 1453 // We don't recurse from the startup snapshot generator into the partial
1423 // snapshot generator. 1454 // snapshot generator.
1424 DCHECK(length == isolate->serialize_partial_snapshot_cache_length() - 1); 1455 DCHECK(length == isolate->serialize_partial_snapshot_cache_length() - 1);
1425 return length; 1456 return length;
1426 } 1457 }
1427 1458
1428 1459
1429 // Encode the location of an already deserialized object in order to write its 1460 bool Serializer::SerializeKnownObject(HeapObject* obj, HowToCode how_to_code,
1430 // location into a later object. We can encode the location as an offset from 1461 WhereToPoint where_to_point, int skip) {
1431 // the start of the deserialized objects or as an offset backwards from the 1462 if (how_to_code == kPlain && where_to_point == kStartOfObject) {
1432 // current allocation pointer. 1463 // Encode a reference to a hot object by its index in the working set.
1433 void Serializer::SerializeBackReference(BackReference back_reference, 1464 int index = hot_objects_.Find(obj);
1434 HowToCode how_to_code, 1465 if (index != HotObjectsList::kNotFound) {
1435 WhereToPoint where_to_point, int skip) { 1466 DCHECK(index >= 0 && index <= kMaxHotObjectIndex);
1436 AllocationSpace space = back_reference.space(); 1467 if (FLAG_trace_serializer) {
1437 if (skip == 0) { 1468 PrintF(" Encoding hot object %d:", index);
1438 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer"); 1469 obj->ShortPrint();
1439 } else { 1470 PrintF("\n");
1440 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space, 1471 }
1441 "BackRefSerWithSkip"); 1472 if (skip != 0) {
1442 sink_->PutInt(skip, "BackRefSkipDistance"); 1473 sink_->Put(kHotObjectWithSkip + index, "HotObjectWithSkip");
1474 sink_->PutInt(skip, "HotObjectSkipDistance");
1475 } else {
1476 sink_->Put(kHotObject + index, "HotObject");
1477 }
1478 return true;
1479 }
1443 } 1480 }
1481 BackReference back_reference = back_reference_map_.Lookup(obj);
1482 if (back_reference.is_valid()) {
1483 // Encode the location of an already deserialized object in order to write
1484 // its location into a later object. We can encode the location as an
1485 // offset fromthe start of the deserialized objects or as an offset
1486 // backwards from thecurrent allocation pointer.
1487 if (back_reference.is_source()) {
1488 FlushSkip(skip);
1489 if (FLAG_trace_serializer) PrintF(" Encoding source object\n");
1490 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject);
1491 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source");
1492 sink_->PutInt(kSourceObjectReference, "kSourceObjectIndex");
1493 } else {
1494 if (FLAG_trace_serializer) {
1495 PrintF(" Encoding back reference to: ");
1496 obj->ShortPrint();
1497 PrintF("\n");
1498 }
1444 1499
1445 sink_->PutInt(back_reference.reference(), 1500 AllocationSpace space = back_reference.space();
1446 (space == LO_SPACE) ? "large object index" : "allocation"); 1501 if (skip == 0) {
1502 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRef");
1503 } else {
1504 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space,
1505 "BackRefWithSkip");
1506 sink_->PutInt(skip, "BackRefSkipDistance");
1507 }
1508 sink_->PutInt(back_reference.reference(), "BackRefValue");
1509
1510 hot_objects_.Add(obj);
1511 }
1512 return true;
1513 }
1514 return false;
1447 } 1515 }
1448 1516
1449 1517
1450 void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, 1518 void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
1451 WhereToPoint where_to_point, int skip) { 1519 WhereToPoint where_to_point, int skip) {
1452 DCHECK(!obj->IsJSFunction()); 1520 DCHECK(!obj->IsJSFunction());
1453 1521
1454 int root_index = root_index_map_.Lookup(obj); 1522 int root_index = root_index_map_.Lookup(obj);
1455 // We can only encode roots as such if it has already been serialized. 1523 // We can only encode roots as such if it has already been serialized.
1456 // That applies to root indices below the wave front. 1524 // That applies to root indices below the wave front.
1457 if (root_index != RootIndexMap::kInvalidRootIndex && 1525 if (root_index != RootIndexMap::kInvalidRootIndex &&
1458 root_index < root_index_wave_front_) { 1526 root_index < root_index_wave_front_) {
1459 PutRoot(root_index, obj, how_to_code, where_to_point, skip); 1527 PutRoot(root_index, obj, how_to_code, where_to_point, skip);
1460 return; 1528 return;
1461 } 1529 }
1462 1530
1463 BackReference back_reference = back_reference_map_.Lookup(obj); 1531 if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return;
1464 if (back_reference.is_valid()) {
1465 SerializeBackReference(back_reference, how_to_code, where_to_point, skip);
1466 return;
1467 }
1468 1532
1469 if (skip != 0) { 1533 FlushSkip(skip);
1470 sink_->Put(kSkip, "FlushPendingSkip");
1471 sink_->PutInt(skip, "SkipDistance");
1472 }
1473 1534
1474 // Object has not yet been serialized. Serialize it here. 1535 // Object has not yet been serialized. Serialize it here.
1475 ObjectSerializer object_serializer(this, obj, sink_, how_to_code, 1536 ObjectSerializer object_serializer(this, obj, sink_, how_to_code,
1476 where_to_point); 1537 where_to_point);
1477 object_serializer.Serialize(); 1538 object_serializer.Serialize();
1478 } 1539 }
1479 1540
1480 1541
1481 void StartupSerializer::SerializeWeakReferences() { 1542 void StartupSerializer::SerializeWeakReferences() {
1482 // This phase comes right after the partial serialization (of the snapshot). 1543 // This phase comes right after the serialization (of the snapshot).
1483 // After we have done the partial serialization the partial snapshot cache 1544 // After we have done the partial serialization the partial snapshot cache
1484 // will contain some references needed to decode the partial snapshot. We 1545 // will contain some references needed to decode the partial snapshot. We
1485 // add one entry with 'undefined' which is the sentinel that the deserializer 1546 // add one entry with 'undefined' which is the sentinel that the deserializer
1486 // uses to know it is done deserializing the array. 1547 // uses to know it is done deserializing the array.
1487 Object* undefined = isolate()->heap()->undefined_value(); 1548 Object* undefined = isolate()->heap()->undefined_value();
1488 VisitPointer(&undefined); 1549 VisitPointer(&undefined);
1489 isolate()->heap()->IterateWeakRoots(this, VISIT_ALL); 1550 isolate()->heap()->IterateWeakRoots(this, VISIT_ALL);
1490 Pad(); 1551 Pad();
1491 } 1552 }
1492 1553
1493 1554
1494 void Serializer::PutRoot(int root_index, 1555 void Serializer::PutRoot(int root_index,
1495 HeapObject* object, 1556 HeapObject* object,
1496 SerializerDeserializer::HowToCode how_to_code, 1557 SerializerDeserializer::HowToCode how_to_code,
1497 SerializerDeserializer::WhereToPoint where_to_point, 1558 SerializerDeserializer::WhereToPoint where_to_point,
1498 int skip) { 1559 int skip) {
1560 if (FLAG_trace_serializer) {
1561 PrintF(" Encoding root %d:", root_index);
1562 object->ShortPrint();
1563 PrintF("\n");
1564 }
1565
1499 if (how_to_code == kPlain && 1566 if (how_to_code == kPlain &&
1500 where_to_point == kStartOfObject && 1567 where_to_point == kStartOfObject &&
1501 root_index < kRootArrayNumberOfConstantEncodings && 1568 root_index < kRootArrayNumberOfConstantEncodings &&
1502 !isolate()->heap()->InNewSpace(object)) { 1569 !isolate()->heap()->InNewSpace(object)) {
1503 if (skip == 0) { 1570 if (skip == 0) {
1504 sink_->Put(kRootArrayConstants + kNoSkipDistance + root_index, 1571 sink_->Put(kRootArrayConstants + kNoSkipDistance + root_index,
1505 "RootConstant"); 1572 "RootConstant");
1506 } else { 1573 } else {
1507 sink_->Put(kRootArrayConstants + kHasSkipDistance + root_index, 1574 sink_->Put(kRootArrayConstants + kHasSkipDistance + root_index,
1508 "RootConstant"); 1575 "RootConstant");
1509 sink_->PutInt(skip, "SkipInPutRoot"); 1576 sink_->PutInt(skip, "SkipInPutRoot");
1510 } 1577 }
1511 } else { 1578 } else {
1512 if (skip != 0) { 1579 FlushSkip(skip);
1513 sink_->Put(kSkip, "SkipFromPutRoot");
1514 sink_->PutInt(skip, "SkipFromPutRootDistance");
1515 }
1516 sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization"); 1580 sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization");
1517 sink_->PutInt(root_index, "root_index"); 1581 sink_->PutInt(root_index, "root_index");
1518 } 1582 }
1519 } 1583 }
1520 1584
1521 1585
1522 void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, 1586 void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
1523 WhereToPoint where_to_point, int skip) { 1587 WhereToPoint where_to_point, int skip) {
1524 if (obj->IsMap()) { 1588 if (obj->IsMap()) {
1525 // The code-caches link to context-specific code objects, which 1589 // The code-caches link to context-specific code objects, which
1526 // the startup and context serializes cannot currently handle. 1590 // the startup and context serializes cannot currently handle.
1527 DCHECK(Map::cast(obj)->code_cache() == obj->GetHeap()->empty_fixed_array()); 1591 DCHECK(Map::cast(obj)->code_cache() == obj->GetHeap()->empty_fixed_array());
1528 } 1592 }
1529 1593
1530 int root_index = root_index_map_.Lookup(obj); 1594 int root_index = root_index_map_.Lookup(obj);
1531 if (root_index != RootIndexMap::kInvalidRootIndex) { 1595 if (root_index != RootIndexMap::kInvalidRootIndex) {
1532 PutRoot(root_index, obj, how_to_code, where_to_point, skip); 1596 PutRoot(root_index, obj, how_to_code, where_to_point, skip);
1533 return; 1597 return;
1534 } 1598 }
1535 1599
1536 if (ShouldBeInThePartialSnapshotCache(obj)) { 1600 if (ShouldBeInThePartialSnapshotCache(obj)) {
1537 if (skip != 0) { 1601 FlushSkip(skip);
1538 sink_->Put(kSkip, "SkipFromSerializeObject");
1539 sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
1540 }
1541 1602
1542 int cache_index = PartialSnapshotCacheIndex(obj); 1603 int cache_index = PartialSnapshotCacheIndex(obj);
1543 sink_->Put(kPartialSnapshotCache + how_to_code + where_to_point, 1604 sink_->Put(kPartialSnapshotCache + how_to_code + where_to_point,
1544 "PartialSnapshotCache"); 1605 "PartialSnapshotCache");
1545 sink_->PutInt(cache_index, "partial_snapshot_cache_index"); 1606 sink_->PutInt(cache_index, "partial_snapshot_cache_index");
1546 return; 1607 return;
1547 } 1608 }
1548 1609
1549 // Pointers from the partial snapshot to the objects in the startup snapshot 1610 // Pointers from the partial snapshot to the objects in the startup snapshot
1550 // should go through the root array or through the partial snapshot cache. 1611 // should go through the root array or through the partial snapshot cache.
1551 // If this is not the case you may have to add something to the root array. 1612 // If this is not the case you may have to add something to the root array.
1552 DCHECK(!startup_serializer_->back_reference_map()->Lookup(obj).is_valid()); 1613 DCHECK(!startup_serializer_->back_reference_map()->Lookup(obj).is_valid());
1553 // All the internalized strings that the partial snapshot needs should be 1614 // All the internalized strings that the partial snapshot needs should be
1554 // either in the root table or in the partial snapshot cache. 1615 // either in the root table or in the partial snapshot cache.
1555 DCHECK(!obj->IsInternalizedString()); 1616 DCHECK(!obj->IsInternalizedString());
1556 1617
1557 BackReference back_reference = back_reference_map_.Lookup(obj); 1618 if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return;
1558 if (back_reference.is_valid()) {
1559 SerializeBackReference(back_reference, how_to_code, where_to_point, skip);
1560 return;
1561 }
1562 1619
1563 if (skip != 0) { 1620 FlushSkip(skip);
1564 sink_->Put(kSkip, "SkipFromSerializeObject"); 1621
1565 sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
1566 }
1567 // Object has not yet been serialized. Serialize it here. 1622 // Object has not yet been serialized. Serialize it here.
1568 ObjectSerializer serializer(this, obj, sink_, how_to_code, where_to_point); 1623 ObjectSerializer serializer(this, obj, sink_, how_to_code, where_to_point);
1569 serializer.Serialize(); 1624 serializer.Serialize();
1570 } 1625 }
1571 1626
1572 1627
1573 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space, 1628 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space,
1574 int size, Map* map) { 1629 int size, Map* map) {
1575 if (serializer_->code_address_map_) { 1630 if (serializer_->code_address_map_) {
1576 const char* code_name = 1631 const char* code_name =
1577 serializer_->code_address_map_->Lookup(object_->address()); 1632 serializer_->code_address_map_->Lookup(object_->address());
1578 LOG(serializer_->isolate_, 1633 LOG(serializer_->isolate_,
1579 CodeNameEvent(object_->address(), sink_->Position(), code_name)); 1634 CodeNameEvent(object_->address(), sink_->Position(), code_name));
1580 LOG(serializer_->isolate_, 1635 LOG(serializer_->isolate_,
1581 SnapshotPositionEvent(object_->address(), sink_->Position())); 1636 SnapshotPositionEvent(object_->address(), sink_->Position()));
1582 } 1637 }
1583 1638
1584 BackReference back_reference; 1639 BackReference back_reference;
1585 if (space == LO_SPACE) { 1640 if (space == LO_SPACE) {
1586 sink_->Put(kNewObject + reference_representation_ + space, 1641 sink_->Put(kNewObject + reference_representation_ + space,
1587 "new large object"); 1642 "NewLargeObject");
1588 sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); 1643 sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords");
1589 if (object_->IsCode()) { 1644 if (object_->IsCode()) {
1590 sink_->Put(EXECUTABLE, "executable large object"); 1645 sink_->Put(EXECUTABLE, "executable large object");
1591 } else { 1646 } else {
1592 sink_->Put(NOT_EXECUTABLE, "not executable large object"); 1647 sink_->Put(NOT_EXECUTABLE, "not executable large object");
1593 } 1648 }
1594 back_reference = serializer_->AllocateLargeObject(size); 1649 back_reference = serializer_->AllocateLargeObject(size);
1595 } else { 1650 } else {
1596 if (object_->NeedsToEnsureDoubleAlignment()) { 1651 if (object_->NeedsToEnsureDoubleAlignment()) {
1597 // Add wriggle room for double alignment padding. 1652 // Add wriggle room for double alignment padding.
1598 back_reference = serializer_->Allocate(space, size + kPointerSize); 1653 back_reference = serializer_->Allocate(space, size + kPointerSize);
1599 sink_->PutInt(kDoubleAlignmentSentinel, "double align"); 1654 sink_->PutInt(kDoubleAlignmentSentinel, "DoubleAlignSentinel");
1600 } else { 1655 } else {
1601 back_reference = serializer_->Allocate(space, size); 1656 back_reference = serializer_->Allocate(space, size);
1602 } 1657 }
1603 sink_->Put(kNewObject + reference_representation_ + space, "new object"); 1658 sink_->Put(kNewObject + reference_representation_ + space, "NewObject");
1604 int encoded_size = size >> kObjectAlignmentBits; 1659 int encoded_size = size >> kObjectAlignmentBits;
1605 DCHECK_NE(kDoubleAlignmentSentinel, encoded_size); 1660 DCHECK_NE(kDoubleAlignmentSentinel, encoded_size);
1606 sink_->PutInt(encoded_size, "Size in words"); 1661 sink_->PutInt(encoded_size, "ObjectSizeInWords");
1607 } 1662 }
1608 1663
1609 // Mark this object as already serialized. 1664 // Mark this object as already serialized.
1610 serializer_->back_reference_map()->Add(object_, back_reference); 1665 serializer_->back_reference_map()->Add(object_, back_reference);
1611 1666
1612 // Serialize the map (first word of the object). 1667 // Serialize the map (first word of the object).
1613 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0); 1668 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0);
1614 } 1669 }
1615 1670
1616 1671
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1670 int padding_size = allocation_size - SeqString::kHeaderSize - content_size; 1725 int padding_size = allocation_size - SeqString::kHeaderSize - content_size;
1671 DCHECK(0 <= padding_size && padding_size < kObjectAlignment); 1726 DCHECK(0 <= padding_size && padding_size < kObjectAlignment);
1672 for (int i = 0; i < padding_size; i++) sink_->PutSection(0, "StringPadding"); 1727 for (int i = 0; i < padding_size; i++) sink_->PutSection(0, "StringPadding");
1673 1728
1674 sink_->Put(kSkip, "SkipAfterString"); 1729 sink_->Put(kSkip, "SkipAfterString");
1675 sink_->PutInt(bytes_to_output, "SkipDistance"); 1730 sink_->PutInt(bytes_to_output, "SkipDistance");
1676 } 1731 }
1677 1732
1678 1733
1679 void Serializer::ObjectSerializer::Serialize() { 1734 void Serializer::ObjectSerializer::Serialize() {
1735 if (FLAG_trace_serializer) {
1736 PrintF(" Encoding heap object: ");
1737 object_->ShortPrint();
1738 PrintF("\n");
1739 }
1740
1680 if (object_->IsExternalString()) { 1741 if (object_->IsExternalString()) {
1681 Heap* heap = serializer_->isolate()->heap(); 1742 Heap* heap = serializer_->isolate()->heap();
1682 if (object_->map() != heap->native_source_string_map()) { 1743 if (object_->map() != heap->native_source_string_map()) {
1683 // Usually we cannot recreate resources for external strings. To work 1744 // Usually we cannot recreate resources for external strings. To work
1684 // around this, external strings are serialized to look like ordinary 1745 // around this, external strings are serialized to look like ordinary
1685 // sequential strings. 1746 // sequential strings.
1686 // The exception are native source code strings, since we can recreate 1747 // The exception are native source code strings, since we can recreate
1687 // their resources. In that case we fall through and leave it to 1748 // their resources. In that case we fall through and leave it to
1688 // VisitExternalOneByteString further down. 1749 // VisitExternalOneByteString further down.
1689 SerializeExternalString(); 1750 SerializeExternalString();
(...skipping 30 matching lines...) Expand all
1720 Heap::RootIsImmortalImmovable(root_index) && 1781 Heap::RootIsImmortalImmovable(root_index) &&
1721 current_contents == current[-1]) { 1782 current_contents == current[-1]) {
1722 DCHECK(!serializer_->isolate()->heap()->InNewSpace(current_contents)); 1783 DCHECK(!serializer_->isolate()->heap()->InNewSpace(current_contents));
1723 int repeat_count = 1; 1784 int repeat_count = 1;
1724 while (&current[repeat_count] < end - 1 && 1785 while (&current[repeat_count] < end - 1 &&
1725 current[repeat_count] == current_contents) { 1786 current[repeat_count] == current_contents) {
1726 repeat_count++; 1787 repeat_count++;
1727 } 1788 }
1728 current += repeat_count; 1789 current += repeat_count;
1729 bytes_processed_so_far_ += repeat_count * kPointerSize; 1790 bytes_processed_so_far_ += repeat_count * kPointerSize;
1730 if (repeat_count > kMaxRepeats) { 1791 if (repeat_count > kMaxFixedRepeats) {
1731 sink_->Put(kRepeat, "SerializeRepeats"); 1792 sink_->Put(kVariableRepeat, "SerializeRepeats");
1732 sink_->PutInt(repeat_count, "SerializeRepeats"); 1793 sink_->PutInt(repeat_count, "SerializeRepeats");
1733 } else { 1794 } else {
1734 sink_->Put(CodeForRepeats(repeat_count), "SerializeRepeats"); 1795 sink_->Put(CodeForRepeats(repeat_count), "SerializeRepeats");
1735 } 1796 }
1736 } else { 1797 } else {
1737 serializer_->SerializeObject( 1798 serializer_->SerializeObject(
1738 current_contents, kPlain, kStartOfObject, 0); 1799 current_contents, kPlain, kStartOfObject, 0);
1739 bytes_processed_so_far_ += kPointerSize; 1800 bytes_processed_so_far_ += kPointerSize;
1740 current++; 1801 current++;
1741 } 1802 }
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1950 } 2011 }
1951 2012
1952 2013
1953 BackReference Serializer::Allocate(AllocationSpace space, int size) { 2014 BackReference Serializer::Allocate(AllocationSpace space, int size) {
1954 DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); 2015 DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces);
1955 DCHECK(size > 0 && size <= static_cast<int>(max_chunk_size(space))); 2016 DCHECK(size > 0 && size <= static_cast<int>(max_chunk_size(space)));
1956 uint32_t new_chunk_size = pending_chunk_[space] + size; 2017 uint32_t new_chunk_size = pending_chunk_[space] + size;
1957 if (new_chunk_size > max_chunk_size(space)) { 2018 if (new_chunk_size > max_chunk_size(space)) {
1958 // The new chunk size would not fit onto a single page. Complete the 2019 // The new chunk size would not fit onto a single page. Complete the
1959 // current chunk and start a new one. 2020 // current chunk and start a new one.
1960 sink_->Put(kNextChunk, "move to next chunk"); 2021 sink_->Put(kNextChunk, "NextChunk");
1961 sink_->Put(space, "space of next chunk"); 2022 sink_->Put(space, "NextChunkSpace");
1962 completed_chunks_[space].Add(pending_chunk_[space]); 2023 completed_chunks_[space].Add(pending_chunk_[space]);
1963 pending_chunk_[space] = 0; 2024 pending_chunk_[space] = 0;
1964 new_chunk_size = size; 2025 new_chunk_size = size;
1965 } 2026 }
1966 uint32_t offset = pending_chunk_[space]; 2027 uint32_t offset = pending_chunk_[space];
1967 pending_chunk_[space] = new_chunk_size; 2028 pending_chunk_[space] = new_chunk_size;
1968 return BackReference::Reference(space, completed_chunks_[space].length(), 2029 return BackReference::Reference(space, completed_chunks_[space].length(),
1969 offset); 2030 offset);
1970 } 2031 }
1971 2032
(...skipping 11 matching lines...) Expand all
1983 isolate_->InitializeLoggingAndCounters(); 2044 isolate_->InitializeLoggingAndCounters();
1984 code_address_map_ = new CodeAddressMap(isolate_); 2045 code_address_map_ = new CodeAddressMap(isolate_);
1985 } 2046 }
1986 2047
1987 2048
1988 ScriptData* CodeSerializer::Serialize(Isolate* isolate, 2049 ScriptData* CodeSerializer::Serialize(Isolate* isolate,
1989 Handle<SharedFunctionInfo> info, 2050 Handle<SharedFunctionInfo> info,
1990 Handle<String> source) { 2051 Handle<String> source) {
1991 base::ElapsedTimer timer; 2052 base::ElapsedTimer timer;
1992 if (FLAG_profile_deserialization) timer.Start(); 2053 if (FLAG_profile_deserialization) timer.Start();
1993 if (FLAG_trace_code_serializer) { 2054 if (FLAG_trace_serializer) {
1994 PrintF("[Serializing from"); 2055 PrintF("[Serializing from");
1995 Object* script = info->script(); 2056 Object* script = info->script();
1996 if (script->IsScript()) Script::cast(script)->name()->ShortPrint(); 2057 if (script->IsScript()) Script::cast(script)->name()->ShortPrint();
1997 PrintF("]\n"); 2058 PrintF("]\n");
1998 } 2059 }
1999 2060
2000 // Serialize code object. 2061 // Serialize code object.
2001 SnapshotByteSink sink(info->code()->CodeSize() * 2); 2062 SnapshotByteSink sink(info->code()->CodeSize() * 2);
2002 CodeSerializer cs(isolate, &sink, *source, info->code()); 2063 CodeSerializer cs(isolate, &sink, *source, info->code());
2003 DisallowHeapAllocation no_gc; 2064 DisallowHeapAllocation no_gc;
(...skipping 19 matching lines...) Expand all
2023 } 2084 }
2024 2085
2025 return script_data; 2086 return script_data;
2026 } 2087 }
2027 2088
2028 2089
2029 void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, 2090 void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
2030 WhereToPoint where_to_point, int skip) { 2091 WhereToPoint where_to_point, int skip) {
2031 int root_index = root_index_map_.Lookup(obj); 2092 int root_index = root_index_map_.Lookup(obj);
2032 if (root_index != RootIndexMap::kInvalidRootIndex) { 2093 if (root_index != RootIndexMap::kInvalidRootIndex) {
2033 if (FLAG_trace_code_serializer) {
2034 PrintF(" Encoding root: %d\n", root_index);
2035 }
2036 PutRoot(root_index, obj, how_to_code, where_to_point, skip); 2094 PutRoot(root_index, obj, how_to_code, where_to_point, skip);
2037 return; 2095 return;
2038 } 2096 }
2039 2097
2040 BackReference back_reference = back_reference_map_.Lookup(obj); 2098 if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return;
2041 if (back_reference.is_valid()) {
2042 if (back_reference.is_source()) {
2043 DCHECK_EQ(source_, obj);
2044 SerializeSourceObject(how_to_code, where_to_point);
2045 } else {
2046 if (FLAG_trace_code_serializer) {
2047 PrintF(" Encoding back reference to: ");
2048 obj->ShortPrint();
2049 PrintF("\n");
2050 }
2051 SerializeBackReference(back_reference, how_to_code, where_to_point, skip);
2052 }
2053 return;
2054 }
2055 2099
2056 if (skip != 0) { 2100 FlushSkip(skip);
2057 sink_->Put(kSkip, "SkipFromSerializeObject");
2058 sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
2059 }
2060 2101
2061 if (obj->IsCode()) { 2102 if (obj->IsCode()) {
2062 Code* code_object = Code::cast(obj); 2103 Code* code_object = Code::cast(obj);
2063 switch (code_object->kind()) { 2104 switch (code_object->kind()) {
2064 case Code::OPTIMIZED_FUNCTION: // No optimized code compiled yet. 2105 case Code::OPTIMIZED_FUNCTION: // No optimized code compiled yet.
2065 case Code::HANDLER: // No handlers patched in yet. 2106 case Code::HANDLER: // No handlers patched in yet.
2066 case Code::REGEXP: // No regexp literals initialized yet. 2107 case Code::REGEXP: // No regexp literals initialized yet.
2067 case Code::NUMBER_OF_KINDS: // Pseudo enum value. 2108 case Code::NUMBER_OF_KINDS: // Pseudo enum value.
2068 CHECK(false); 2109 CHECK(false);
2069 case Code::BUILTIN: 2110 case Code::BUILTIN:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2102 // We expect no instantiated function objects or contexts. 2143 // We expect no instantiated function objects or contexts.
2103 CHECK(!obj->IsJSFunction() && !obj->IsContext()); 2144 CHECK(!obj->IsJSFunction() && !obj->IsContext());
2104 2145
2105 SerializeGeneric(obj, how_to_code, where_to_point); 2146 SerializeGeneric(obj, how_to_code, where_to_point);
2106 } 2147 }
2107 2148
2108 2149
2109 void CodeSerializer::SerializeGeneric(HeapObject* heap_object, 2150 void CodeSerializer::SerializeGeneric(HeapObject* heap_object,
2110 HowToCode how_to_code, 2151 HowToCode how_to_code,
2111 WhereToPoint where_to_point) { 2152 WhereToPoint where_to_point) {
2112 if (FLAG_trace_code_serializer) {
2113 PrintF(" Encoding heap object: ");
2114 heap_object->ShortPrint();
2115 PrintF("\n");
2116 }
2117
2118 if (heap_object->IsInternalizedString()) num_internalized_strings_++; 2153 if (heap_object->IsInternalizedString()) num_internalized_strings_++;
2119 2154
2120 // Object has not yet been serialized. Serialize it here. 2155 // Object has not yet been serialized. Serialize it here.
2121 ObjectSerializer serializer(this, heap_object, sink_, how_to_code, 2156 ObjectSerializer serializer(this, heap_object, sink_, how_to_code,
2122 where_to_point); 2157 where_to_point);
2123 serializer.Serialize(); 2158 serializer.Serialize();
2124 } 2159 }
2125 2160
2126 2161
2127 void CodeSerializer::SerializeBuiltin(int builtin_index, HowToCode how_to_code, 2162 void CodeSerializer::SerializeBuiltin(int builtin_index, HowToCode how_to_code,
2128 WhereToPoint where_to_point) { 2163 WhereToPoint where_to_point) {
2129 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || 2164 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) ||
2130 (how_to_code == kPlain && where_to_point == kInnerPointer) || 2165 (how_to_code == kPlain && where_to_point == kInnerPointer) ||
2131 (how_to_code == kFromCode && where_to_point == kInnerPointer)); 2166 (how_to_code == kFromCode && where_to_point == kInnerPointer));
2132 DCHECK_LT(builtin_index, Builtins::builtin_count); 2167 DCHECK_LT(builtin_index, Builtins::builtin_count);
2133 DCHECK_LE(0, builtin_index); 2168 DCHECK_LE(0, builtin_index);
2134 2169
2135 if (FLAG_trace_code_serializer) { 2170 if (FLAG_trace_serializer) {
2136 PrintF(" Encoding builtin: %s\n", 2171 PrintF(" Encoding builtin: %s\n",
2137 isolate()->builtins()->name(builtin_index)); 2172 isolate()->builtins()->name(builtin_index));
2138 } 2173 }
2139 2174
2140 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin"); 2175 sink_->Put(kBuiltin + how_to_code + where_to_point, "Builtin");
2141 sink_->PutInt(builtin_index, "builtin_index"); 2176 sink_->PutInt(builtin_index, "builtin_index");
2142 } 2177 }
2143 2178
2144 2179
2145 void CodeSerializer::SerializeCodeStub(uint32_t stub_key, HowToCode how_to_code, 2180 void CodeSerializer::SerializeCodeStub(uint32_t stub_key, HowToCode how_to_code,
2146 WhereToPoint where_to_point) { 2181 WhereToPoint where_to_point) {
2147 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) || 2182 DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) ||
2148 (how_to_code == kPlain && where_to_point == kInnerPointer) || 2183 (how_to_code == kPlain && where_to_point == kInnerPointer) ||
2149 (how_to_code == kFromCode && where_to_point == kInnerPointer)); 2184 (how_to_code == kFromCode && where_to_point == kInnerPointer));
2150 DCHECK(CodeStub::MajorKeyFromKey(stub_key) != CodeStub::NoCache); 2185 DCHECK(CodeStub::MajorKeyFromKey(stub_key) != CodeStub::NoCache);
2151 DCHECK(!CodeStub::GetCode(isolate(), stub_key).is_null()); 2186 DCHECK(!CodeStub::GetCode(isolate(), stub_key).is_null());
2152 2187
2153 int index = AddCodeStubKey(stub_key) + kCodeStubsBaseIndex; 2188 int index = AddCodeStubKey(stub_key) + kCodeStubsBaseIndex;
2154 2189
2155 if (FLAG_trace_code_serializer) { 2190 if (FLAG_trace_serializer) {
2156 PrintF(" Encoding code stub %s as %d\n", 2191 PrintF(" Encoding code stub %s as %d\n",
2157 CodeStub::MajorName(CodeStub::MajorKeyFromKey(stub_key), false), 2192 CodeStub::MajorName(CodeStub::MajorKeyFromKey(stub_key), false),
2158 index); 2193 index);
2159 } 2194 }
2160 2195
2161 sink_->Put(kAttachedReference + how_to_code + where_to_point, "CodeStub"); 2196 sink_->Put(kAttachedReference + how_to_code + where_to_point, "CodeStub");
2162 sink_->PutInt(index, "CodeStub key"); 2197 sink_->PutInt(index, "CodeStub key");
2163 } 2198 }
2164 2199
2165 2200
2166 void CodeSerializer::SerializeIC(Code* ic, HowToCode how_to_code, 2201 void CodeSerializer::SerializeIC(Code* ic, HowToCode how_to_code,
2167 WhereToPoint where_to_point) { 2202 WhereToPoint where_to_point) {
2168 // The IC may be implemented as a stub. 2203 // The IC may be implemented as a stub.
2169 uint32_t stub_key = ic->stub_key(); 2204 uint32_t stub_key = ic->stub_key();
2170 if (stub_key != CodeStub::NoCacheKey()) { 2205 if (stub_key != CodeStub::NoCacheKey()) {
2171 if (FLAG_trace_code_serializer) { 2206 if (FLAG_trace_serializer) {
2172 PrintF(" %s is a code stub\n", Code::Kind2String(ic->kind())); 2207 PrintF(" %s is a code stub\n", Code::Kind2String(ic->kind()));
2173 } 2208 }
2174 SerializeCodeStub(stub_key, how_to_code, where_to_point); 2209 SerializeCodeStub(stub_key, how_to_code, where_to_point);
2175 return; 2210 return;
2176 } 2211 }
2177 // The IC may be implemented as builtin. Only real builtins have an 2212 // The IC may be implemented as builtin. Only real builtins have an
2178 // actual builtin_index value attached (otherwise it's just garbage). 2213 // actual builtin_index value attached (otherwise it's just garbage).
2179 // Compare to make sure we are really dealing with a builtin. 2214 // Compare to make sure we are really dealing with a builtin.
2180 int builtin_index = ic->builtin_index(); 2215 int builtin_index = ic->builtin_index();
2181 if (builtin_index < Builtins::builtin_count) { 2216 if (builtin_index < Builtins::builtin_count) {
2182 Builtins::Name name = static_cast<Builtins::Name>(builtin_index); 2217 Builtins::Name name = static_cast<Builtins::Name>(builtin_index);
2183 Code* builtin = isolate()->builtins()->builtin(name); 2218 Code* builtin = isolate()->builtins()->builtin(name);
2184 if (builtin == ic) { 2219 if (builtin == ic) {
2185 if (FLAG_trace_code_serializer) { 2220 if (FLAG_trace_serializer) {
2186 PrintF(" %s is a builtin\n", Code::Kind2String(ic->kind())); 2221 PrintF(" %s is a builtin\n", Code::Kind2String(ic->kind()));
2187 } 2222 }
2188 DCHECK(ic->kind() == Code::KEYED_LOAD_IC || 2223 DCHECK(ic->kind() == Code::KEYED_LOAD_IC ||
2189 ic->kind() == Code::KEYED_STORE_IC); 2224 ic->kind() == Code::KEYED_STORE_IC);
2190 SerializeBuiltin(builtin_index, how_to_code, where_to_point); 2225 SerializeBuiltin(builtin_index, how_to_code, where_to_point);
2191 return; 2226 return;
2192 } 2227 }
2193 } 2228 }
2194 // The IC may also just be a piece of code kept in the non_monomorphic_cache. 2229 // The IC may also just be a piece of code kept in the non_monomorphic_cache.
2195 // In that case, just serialize as a normal code object. 2230 // In that case, just serialize as a normal code object.
2196 if (FLAG_trace_code_serializer) { 2231 if (FLAG_trace_serializer) {
2197 PrintF(" %s has no special handling\n", Code::Kind2String(ic->kind())); 2232 PrintF(" %s has no special handling\n", Code::Kind2String(ic->kind()));
2198 } 2233 }
2199 DCHECK(ic->kind() == Code::LOAD_IC || ic->kind() == Code::STORE_IC); 2234 DCHECK(ic->kind() == Code::LOAD_IC || ic->kind() == Code::STORE_IC);
2200 SerializeGeneric(ic, how_to_code, where_to_point); 2235 SerializeGeneric(ic, how_to_code, where_to_point);
2201 } 2236 }
2202 2237
2203 2238
2204 int CodeSerializer::AddCodeStubKey(uint32_t stub_key) { 2239 int CodeSerializer::AddCodeStubKey(uint32_t stub_key) {
2205 // TODO(yangguo) Maybe we need a hash table for a faster lookup than O(n^2). 2240 // TODO(yangguo) Maybe we need a hash table for a faster lookup than O(n^2).
2206 int index = 0; 2241 int index = 0;
2207 while (index < stub_keys_.length()) { 2242 while (index < stub_keys_.length()) {
2208 if (stub_keys_[index] == stub_key) return index; 2243 if (stub_keys_[index] == stub_key) return index;
2209 index++; 2244 index++;
2210 } 2245 }
2211 stub_keys_.Add(stub_key); 2246 stub_keys_.Add(stub_key);
2212 return index; 2247 return index;
2213 } 2248 }
2214 2249
2215 2250
2216 void CodeSerializer::SerializeSourceObject(HowToCode how_to_code, 2251 void CodeSerializer::SerializeSourceObject(HowToCode how_to_code,
2217 WhereToPoint where_to_point) { 2252 WhereToPoint where_to_point) {
2218 if (FLAG_trace_code_serializer) PrintF(" Encoding source object\n"); 2253 if (FLAG_trace_serializer) PrintF(" Encoding source object\n");
2219 2254
2220 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject); 2255 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject);
2221 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source"); 2256 sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source");
2222 sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex"); 2257 sink_->PutInt(kSourceObjectIndex, "kSourceObjectIndex");
2223 } 2258 }
2224 2259
2225 2260
2226 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize( 2261 MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
2227 Isolate* isolate, ScriptData* cached_data, Handle<String> source) { 2262 Isolate* isolate, ScriptData* cached_data, Handle<String> source) {
2228 base::ElapsedTimer timer; 2263 base::ElapsedTimer timer;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2356 bool SerializedCodeData::IsSane(String* source) { 2391 bool SerializedCodeData::IsSane(String* source) {
2357 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && 2392 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) &&
2358 PayloadLength() >= SharedFunctionInfo::kSize; 2393 PayloadLength() >= SharedFunctionInfo::kSize;
2359 } 2394 }
2360 2395
2361 2396
2362 int SerializedCodeData::CheckSum(String* string) { 2397 int SerializedCodeData::CheckSum(String* string) {
2363 return Version::Hash() ^ string->length(); 2398 return Version::Hash() ^ string->length();
2364 } 2399 }
2365 } } // namespace v8::internal 2400 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/serialize.h ('k') | src/snapshot-source-sink.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698