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 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 | 589 |
590 NameMap address_to_name_map_; | 590 NameMap address_to_name_map_; |
591 Isolate* isolate_; | 591 Isolate* isolate_; |
592 }; | 592 }; |
593 | 593 |
594 | 594 |
595 Deserializer::Deserializer(SnapshotByteSource* source) | 595 Deserializer::Deserializer(SnapshotByteSource* source) |
596 : isolate_(NULL), | 596 : isolate_(NULL), |
597 attached_objects_(NULL), | 597 attached_objects_(NULL), |
598 source_(source), | 598 source_(source), |
599 external_reference_decoder_(NULL) { | 599 external_reference_decoder_(NULL), |
600 for (int i = 0; i < LAST_SPACE + 1; i++) { | 600 deserialized_large_objects_(0) { |
| 601 for (int i = 0; i < kNumberOfSpaces; i++) { |
601 reservations_[i] = kUninitializedReservation; | 602 reservations_[i] = kUninitializedReservation; |
602 } | 603 } |
603 } | 604 } |
604 | 605 |
605 | 606 |
606 void Deserializer::FlushICacheForNewCodeObjects() { | 607 void Deserializer::FlushICacheForNewCodeObjects() { |
607 PageIterator it(isolate_->heap()->code_space()); | 608 PageIterator it(isolate_->heap()->code_space()); |
608 while (it.has_next()) { | 609 while (it.has_next()) { |
609 Page* p = it.next(); | 610 Page* p = it.next(); |
610 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start()); | 611 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start()); |
611 } | 612 } |
612 } | 613 } |
613 | 614 |
614 | 615 |
615 void Deserializer::Deserialize(Isolate* isolate) { | 616 void Deserializer::Deserialize(Isolate* isolate) { |
616 isolate_ = isolate; | 617 isolate_ = isolate; |
617 DCHECK(isolate_ != NULL); | 618 DCHECK(isolate_ != NULL); |
618 isolate_->heap()->ReserveSpace(reservations_, &high_water_[0]); | 619 isolate_->heap()->ReserveSpace(reservations_, high_water_); |
619 // No active threads. | 620 // No active threads. |
620 DCHECK_EQ(NULL, isolate_->thread_manager()->FirstThreadStateInUse()); | 621 DCHECK_EQ(NULL, isolate_->thread_manager()->FirstThreadStateInUse()); |
621 // No active handles. | 622 // No active handles. |
622 DCHECK(isolate_->handle_scope_implementer()->blocks()->is_empty()); | 623 DCHECK(isolate_->handle_scope_implementer()->blocks()->is_empty()); |
623 DCHECK_EQ(NULL, external_reference_decoder_); | 624 DCHECK_EQ(NULL, external_reference_decoder_); |
624 external_reference_decoder_ = new ExternalReferenceDecoder(isolate); | 625 external_reference_decoder_ = new ExternalReferenceDecoder(isolate); |
625 isolate_->heap()->IterateSmiRoots(this); | 626 isolate_->heap()->IterateSmiRoots(this); |
626 isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); | 627 isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); |
627 isolate_->heap()->RepairFreeListsAfterBoot(); | 628 isolate_->heap()->RepairFreeListsAfterBoot(); |
628 isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); | 629 isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); |
(...skipping 26 matching lines...) Expand all Loading... |
655 LOG_CODE_EVENT(isolate_, LogCodeObjects()); | 656 LOG_CODE_EVENT(isolate_, LogCodeObjects()); |
656 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); | 657 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); |
657 } | 658 } |
658 | 659 |
659 | 660 |
660 void Deserializer::DeserializePartial(Isolate* isolate, Object** root) { | 661 void Deserializer::DeserializePartial(Isolate* isolate, Object** root) { |
661 isolate_ = isolate; | 662 isolate_ = isolate; |
662 for (int i = NEW_SPACE; i < kNumberOfSpaces; i++) { | 663 for (int i = NEW_SPACE; i < kNumberOfSpaces; i++) { |
663 DCHECK(reservations_[i] != kUninitializedReservation); | 664 DCHECK(reservations_[i] != kUninitializedReservation); |
664 } | 665 } |
665 isolate_->heap()->ReserveSpace(reservations_, &high_water_[0]); | 666 Heap* heap = isolate->heap(); |
| 667 heap->ReserveSpace(reservations_, high_water_); |
666 if (external_reference_decoder_ == NULL) { | 668 if (external_reference_decoder_ == NULL) { |
667 external_reference_decoder_ = new ExternalReferenceDecoder(isolate); | 669 external_reference_decoder_ = new ExternalReferenceDecoder(isolate); |
668 } | 670 } |
669 | 671 |
670 DisallowHeapAllocation no_gc; | 672 DisallowHeapAllocation no_gc; |
671 | 673 |
672 // Keep track of the code space start and end pointers in case new | 674 // Keep track of the code space start and end pointers in case new |
673 // code objects were unserialized | 675 // code objects were unserialized |
674 OldSpace* code_space = isolate_->heap()->code_space(); | 676 OldSpace* code_space = isolate_->heap()->code_space(); |
675 Address start_address = code_space->top(); | 677 Address start_address = code_space->top(); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
791 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() | 793 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() |
792 // as a (weak) root. If this root is relocated correctly, | 794 // as a (weak) root. If this root is relocated correctly, |
793 // RelinkAllocationSite() isn't necessary. | 795 // RelinkAllocationSite() isn't necessary. |
794 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); | 796 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); |
795 | 797 |
796 // Fix up strings from serialized user code. | 798 // Fix up strings from serialized user code. |
797 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); | 799 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); |
798 | 800 |
799 *write_back = obj; | 801 *write_back = obj; |
800 #ifdef DEBUG | 802 #ifdef DEBUG |
801 bool is_codespace = (space_number == CODE_SPACE); | 803 if (obj->IsCode()) { |
802 DCHECK(obj->IsCode() == is_codespace); | 804 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE); |
| 805 } else { |
| 806 DCHECK(space_number != CODE_SPACE); |
| 807 } |
803 #endif | 808 #endif |
804 } | 809 } |
805 | 810 |
| 811 |
| 812 // We know the space requirements before deserialization and can |
| 813 // pre-allocate that reserved space. During deserialization, all we need |
| 814 // to do is to bump up the pointer for each space in the reserved |
| 815 // space. This is also used for fixing back references. |
| 816 // Since multiple large objects cannot be folded into one large object |
| 817 // space allocation, we have to do an actual allocation when deserializing |
| 818 // each large object. Instead of tracking offset for back references, we |
| 819 // reference large objects by index. |
| 820 Address Deserializer::Allocate(int space_index, int size) { |
| 821 if (space_index == LO_SPACE) { |
| 822 AlwaysAllocateScope scope(isolate_); |
| 823 LargeObjectSpace* lo_space = isolate_->heap()->lo_space(); |
| 824 Executability exec = static_cast<Executability>(source_->GetInt()); |
| 825 AllocationResult result = lo_space->AllocateRaw(size, exec); |
| 826 HeapObject* obj = HeapObject::cast(result.ToObjectChecked()); |
| 827 deserialized_large_objects_.Add(obj); |
| 828 return obj->address(); |
| 829 } else { |
| 830 DCHECK(space_index < kNumberOfPreallocatedSpaces); |
| 831 Address address = high_water_[space_index]; |
| 832 high_water_[space_index] = address + size; |
| 833 return address; |
| 834 } |
| 835 } |
| 836 |
806 void Deserializer::ReadChunk(Object** current, | 837 void Deserializer::ReadChunk(Object** current, |
807 Object** limit, | 838 Object** limit, |
808 int source_space, | 839 int source_space, |
809 Address current_object_address) { | 840 Address current_object_address) { |
810 Isolate* const isolate = isolate_; | 841 Isolate* const isolate = isolate_; |
811 // Write barrier support costs around 1% in startup time. In fact there | 842 // Write barrier support costs around 1% in startup time. In fact there |
812 // are no new space objects in current boot snapshots, so it's not needed, | 843 // are no new space objects in current boot snapshots, so it's not needed, |
813 // but that may change. | 844 // but that may change. |
814 bool write_barrier_needed = (current_object_address != NULL && | 845 bool write_barrier_needed = (current_object_address != NULL && |
815 source_space != NEW_SPACE && | 846 source_space != NEW_SPACE && |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 } \ | 949 } \ |
919 if (!current_was_incremented) { \ | 950 if (!current_was_incremented) { \ |
920 current++; \ | 951 current++; \ |
921 } \ | 952 } \ |
922 break; \ | 953 break; \ |
923 } | 954 } |
924 | 955 |
925 // This generates a case and a body for the new space (which has to do extra | 956 // This generates a case and a body for the new space (which has to do extra |
926 // write barrier handling) and handles the other spaces with 8 fall-through | 957 // write barrier handling) and handles the other spaces with 8 fall-through |
927 // cases and one body. | 958 // cases and one body. |
928 #define ALL_SPACES(where, how, within) \ | 959 #define ALL_SPACES(where, how, within) \ |
929 CASE_STATEMENT(where, how, within, NEW_SPACE) \ | 960 CASE_STATEMENT(where, how, within, NEW_SPACE) \ |
930 CASE_BODY(where, how, within, NEW_SPACE) \ | 961 CASE_BODY(where, how, within, NEW_SPACE) \ |
931 CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \ | 962 CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \ |
932 CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \ | 963 CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \ |
933 CASE_STATEMENT(where, how, within, CODE_SPACE) \ | 964 CASE_STATEMENT(where, how, within, CODE_SPACE) \ |
934 CASE_STATEMENT(where, how, within, CELL_SPACE) \ | 965 CASE_STATEMENT(where, how, within, MAP_SPACE) \ |
935 CASE_STATEMENT(where, how, within, PROPERTY_CELL_SPACE) \ | 966 CASE_STATEMENT(where, how, within, CELL_SPACE) \ |
936 CASE_STATEMENT(where, how, within, MAP_SPACE) \ | 967 CASE_STATEMENT(where, how, within, PROPERTY_CELL_SPACE) \ |
| 968 CASE_STATEMENT(where, how, within, LO_SPACE) \ |
937 CASE_BODY(where, how, within, kAnyOldSpace) | 969 CASE_BODY(where, how, within, kAnyOldSpace) |
938 | 970 |
939 #define FOUR_CASES(byte_code) \ | 971 #define FOUR_CASES(byte_code) \ |
940 case byte_code: \ | 972 case byte_code: \ |
941 case byte_code + 1: \ | 973 case byte_code + 1: \ |
942 case byte_code + 2: \ | 974 case byte_code + 2: \ |
943 case byte_code + 3: | 975 case byte_code + 3: |
944 | 976 |
945 #define SIXTEEN_CASES(byte_code) \ | 977 #define SIXTEEN_CASES(byte_code) \ |
946 FOUR_CASES(byte_code) \ | 978 FOUR_CASES(byte_code) \ |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 } | 1209 } |
1178 DCHECK_EQ(limit, current); | 1210 DCHECK_EQ(limit, current); |
1179 } | 1211 } |
1180 | 1212 |
1181 | 1213 |
1182 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) | 1214 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) |
1183 : isolate_(isolate), | 1215 : isolate_(isolate), |
1184 sink_(sink), | 1216 sink_(sink), |
1185 external_reference_encoder_(new ExternalReferenceEncoder(isolate)), | 1217 external_reference_encoder_(new ExternalReferenceEncoder(isolate)), |
1186 root_index_wave_front_(0), | 1218 root_index_wave_front_(0), |
1187 code_address_map_(NULL) { | 1219 code_address_map_(NULL), |
| 1220 seen_large_objects_index_(0) { |
1188 // The serializer is meant to be used only to generate initial heap images | 1221 // The serializer is meant to be used only to generate initial heap images |
1189 // from a context in which there is only one isolate. | 1222 // from a context in which there is only one isolate. |
1190 for (int i = 0; i <= LAST_SPACE; i++) { | 1223 for (int i = 0; i < kNumberOfSpaces; i++) fullness_[i] = 0; |
1191 fullness_[i] = 0; | |
1192 } | |
1193 } | 1224 } |
1194 | 1225 |
1195 | 1226 |
1196 Serializer::~Serializer() { | 1227 Serializer::~Serializer() { |
1197 delete external_reference_encoder_; | 1228 delete external_reference_encoder_; |
1198 if (code_address_map_ != NULL) delete code_address_map_; | 1229 if (code_address_map_ != NULL) delete code_address_map_; |
1199 } | 1230 } |
1200 | 1231 |
1201 | 1232 |
1202 void StartupSerializer::SerializeStrongReferences() { | 1233 void StartupSerializer::SerializeStrongReferences() { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1317 | 1348 |
1318 // Encode the location of an already deserialized object in order to write its | 1349 // Encode the location of an already deserialized object in order to write its |
1319 // location into a later object. We can encode the location as an offset from | 1350 // location into a later object. We can encode the location as an offset from |
1320 // the start of the deserialized objects or as an offset backwards from the | 1351 // the start of the deserialized objects or as an offset backwards from the |
1321 // current allocation pointer. | 1352 // current allocation pointer. |
1322 void Serializer::SerializeReferenceToPreviousObject(HeapObject* heap_object, | 1353 void Serializer::SerializeReferenceToPreviousObject(HeapObject* heap_object, |
1323 HowToCode how_to_code, | 1354 HowToCode how_to_code, |
1324 WhereToPoint where_to_point, | 1355 WhereToPoint where_to_point, |
1325 int skip) { | 1356 int skip) { |
1326 int space = SpaceOfObject(heap_object); | 1357 int space = SpaceOfObject(heap_object); |
1327 int address = address_mapper_.MappedTo(heap_object); | 1358 |
1328 int offset = CurrentAllocationAddress(space) - address; | |
1329 // Shift out the bits that are always 0. | |
1330 offset >>= kObjectAlignmentBits; | |
1331 if (skip == 0) { | 1359 if (skip == 0) { |
1332 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer"); | 1360 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer"); |
1333 } else { | 1361 } else { |
1334 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space, | 1362 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space, |
1335 "BackRefSerWithSkip"); | 1363 "BackRefSerWithSkip"); |
1336 sink_->PutInt(skip, "BackRefSkipDistance"); | 1364 sink_->PutInt(skip, "BackRefSkipDistance"); |
1337 } | 1365 } |
1338 sink_->PutInt(offset, "offset"); | 1366 |
| 1367 if (space == LO_SPACE) { |
| 1368 int index = address_mapper_.MappedTo(heap_object); |
| 1369 sink_->PutInt(index, "large object index"); |
| 1370 } else { |
| 1371 int address = address_mapper_.MappedTo(heap_object); |
| 1372 int offset = CurrentAllocationAddress(space) - address; |
| 1373 // Shift out the bits that are always 0. |
| 1374 offset >>= kObjectAlignmentBits; |
| 1375 sink_->PutInt(offset, "offset"); |
| 1376 } |
1339 } | 1377 } |
1340 | 1378 |
1341 | 1379 |
1342 void StartupSerializer::SerializeObject( | 1380 void StartupSerializer::SerializeObject( |
1343 Object* o, | 1381 Object* o, |
1344 HowToCode how_to_code, | 1382 HowToCode how_to_code, |
1345 WhereToPoint where_to_point, | 1383 WhereToPoint where_to_point, |
1346 int skip) { | 1384 int skip) { |
1347 CHECK(o->IsHeapObject()); | 1385 CHECK(o->IsHeapObject()); |
1348 HeapObject* heap_object = HeapObject::cast(o); | 1386 HeapObject* heap_object = HeapObject::cast(o); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1487 if (serializer_->code_address_map_) { | 1525 if (serializer_->code_address_map_) { |
1488 const char* code_name = | 1526 const char* code_name = |
1489 serializer_->code_address_map_->Lookup(object_->address()); | 1527 serializer_->code_address_map_->Lookup(object_->address()); |
1490 LOG(serializer_->isolate_, | 1528 LOG(serializer_->isolate_, |
1491 CodeNameEvent(object_->address(), sink_->Position(), code_name)); | 1529 CodeNameEvent(object_->address(), sink_->Position(), code_name)); |
1492 LOG(serializer_->isolate_, | 1530 LOG(serializer_->isolate_, |
1493 SnapshotPositionEvent(object_->address(), sink_->Position())); | 1531 SnapshotPositionEvent(object_->address(), sink_->Position())); |
1494 } | 1532 } |
1495 | 1533 |
1496 // Mark this object as already serialized. | 1534 // Mark this object as already serialized. |
1497 int offset = serializer_->Allocate(space, size); | 1535 if (space == LO_SPACE) { |
1498 serializer_->address_mapper()->AddMapping(object_, offset); | 1536 if (object_->IsCode()) { |
| 1537 sink_->PutInt(EXECUTABLE, "executable large object"); |
| 1538 } else { |
| 1539 sink_->PutInt(NOT_EXECUTABLE, "not executable large object"); |
| 1540 } |
| 1541 int index = serializer_->AllocateLargeObject(size); |
| 1542 serializer_->address_mapper()->AddMapping(object_, index); |
| 1543 } else { |
| 1544 int offset = serializer_->Allocate(space, size); |
| 1545 serializer_->address_mapper()->AddMapping(object_, offset); |
| 1546 } |
1499 | 1547 |
1500 // Serialize the map (first word of the object). | 1548 // Serialize the map (first word of the object). |
1501 serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject, 0); | 1549 serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject, 0); |
1502 | 1550 |
1503 // Serialize the rest of the object. | 1551 // Serialize the rest of the object. |
1504 CHECK_EQ(0, bytes_processed_so_far_); | 1552 CHECK_EQ(0, bytes_processed_so_far_); |
1505 bytes_processed_so_far_ = kPointerSize; | 1553 bytes_processed_so_far_ = kPointerSize; |
1506 object_->IterateBody(object_->map()->instance_type(), size, this); | 1554 object_->IterateBody(object_->map()->instance_type(), size, this); |
1507 OutputRawData(object_->address() + size); | 1555 OutputRawData(object_->address() + size); |
1508 } | 1556 } |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1740 if (object->GetHeap()->InSpace(object, s)) { | 1788 if (object->GetHeap()->InSpace(object, s)) { |
1741 DCHECK(i < kNumberOfSpaces); | 1789 DCHECK(i < kNumberOfSpaces); |
1742 return i; | 1790 return i; |
1743 } | 1791 } |
1744 } | 1792 } |
1745 UNREACHABLE(); | 1793 UNREACHABLE(); |
1746 return 0; | 1794 return 0; |
1747 } | 1795 } |
1748 | 1796 |
1749 | 1797 |
| 1798 int Serializer::AllocateLargeObject(int size) { |
| 1799 fullness_[LO_SPACE] += size; |
| 1800 return seen_large_objects_index_++; |
| 1801 } |
| 1802 |
| 1803 |
1750 int Serializer::Allocate(int space, int size) { | 1804 int Serializer::Allocate(int space, int size) { |
1751 CHECK(space >= 0 && space < kNumberOfSpaces); | 1805 CHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); |
1752 int allocation_address = fullness_[space]; | 1806 int allocation_address = fullness_[space]; |
1753 fullness_[space] = allocation_address + size; | 1807 fullness_[space] = allocation_address + size; |
1754 return allocation_address; | 1808 return allocation_address; |
1755 } | 1809 } |
1756 | 1810 |
1757 | 1811 |
1758 int Serializer::SpaceAreaSize(int space) { | 1812 int Serializer::SpaceAreaSize(int space) { |
1759 if (space == CODE_SPACE) { | 1813 if (space == CODE_SPACE) { |
1760 return isolate_->memory_allocator()->CodePageAreaSize(); | 1814 return isolate_->memory_allocator()->CodePageAreaSize(); |
1761 } else { | 1815 } else { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1833 DCHECK(!heap_object->IsHashTable()); | 1887 DCHECK(!heap_object->IsHashTable()); |
1834 | 1888 |
1835 if (address_mapper_.IsMapped(heap_object)) { | 1889 if (address_mapper_.IsMapped(heap_object)) { |
1836 SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point, | 1890 SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point, |
1837 skip); | 1891 skip); |
1838 return; | 1892 return; |
1839 } | 1893 } |
1840 | 1894 |
1841 if (heap_object->IsCode()) { | 1895 if (heap_object->IsCode()) { |
1842 Code* code_object = Code::cast(heap_object); | 1896 Code* code_object = Code::cast(heap_object); |
| 1897 DCHECK(!code_object->is_optimized_code()); |
1843 if (code_object->kind() == Code::BUILTIN) { | 1898 if (code_object->kind() == Code::BUILTIN) { |
1844 SerializeBuiltin(code_object, how_to_code, where_to_point, skip); | 1899 SerializeBuiltin(code_object, how_to_code, where_to_point, skip); |
1845 return; | 1900 return; |
1846 } | 1901 } else if (code_object->IsCodeStubOrIC()) { |
1847 if (code_object->IsCodeStubOrIC()) { | |
1848 SerializeCodeStub(code_object, how_to_code, where_to_point, skip); | 1902 SerializeCodeStub(code_object, how_to_code, where_to_point, skip); |
1849 return; | 1903 return; |
1850 } | 1904 } |
1851 code_object->ClearInlineCaches(); | 1905 code_object->ClearInlineCaches(); |
1852 } | 1906 } |
1853 | 1907 |
1854 if (heap_object == source_) { | 1908 if (heap_object == source_) { |
1855 SerializeSourceObject(how_to_code, where_to_point, skip); | 1909 SerializeSourceObject(how_to_code, where_to_point, skip); |
1856 return; | 1910 return; |
1857 } | 1911 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1984 | 2038 |
1985 Object* root; | 2039 Object* root; |
1986 | 2040 |
1987 { | 2041 { |
1988 HandleScope scope(isolate); | 2042 HandleScope scope(isolate); |
1989 | 2043 |
1990 SerializedCodeData scd(data, *source); | 2044 SerializedCodeData scd(data, *source); |
1991 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); | 2045 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); |
1992 Deserializer deserializer(&payload); | 2046 Deserializer deserializer(&payload); |
1993 STATIC_ASSERT(NEW_SPACE == 0); | 2047 STATIC_ASSERT(NEW_SPACE == 0); |
1994 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { | 2048 for (int i = NEW_SPACE; i < kNumberOfSpaces; i++) { |
1995 deserializer.set_reservation(i, scd.GetReservation(i)); | 2049 deserializer.set_reservation(i, scd.GetReservation(i)); |
1996 } | 2050 } |
1997 | 2051 |
1998 // Prepare and register list of attached objects. | 2052 // Prepare and register list of attached objects. |
1999 Vector<const uint32_t> code_stub_keys = scd.CodeStubKeys(); | 2053 Vector<const uint32_t> code_stub_keys = scd.CodeStubKeys(); |
2000 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New( | 2054 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New( |
2001 code_stub_keys.length() + kCodeStubsBaseIndex); | 2055 code_stub_keys.length() + kCodeStubsBaseIndex); |
2002 attached_objects[kSourceObjectIndex] = source; | 2056 attached_objects[kSourceObjectIndex] = source; |
2003 for (int i = 0; i < code_stub_keys.length(); i++) { | 2057 for (int i = 0; i < code_stub_keys.length(); i++) { |
2004 attached_objects[i + kCodeStubsBaseIndex] = | 2058 attached_objects[i + kCodeStubsBaseIndex] = |
(...skipping 29 matching lines...) Expand all Loading... |
2034 byte* data = NewArray<byte>(data_length); | 2088 byte* data = NewArray<byte>(data_length); |
2035 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); | 2089 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); |
2036 script_data_ = new ScriptData(data, data_length); | 2090 script_data_ = new ScriptData(data, data_length); |
2037 script_data_->AcquireDataOwnership(); | 2091 script_data_->AcquireDataOwnership(); |
2038 | 2092 |
2039 // Set header values. | 2093 // Set header values. |
2040 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); | 2094 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); |
2041 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); | 2095 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); |
2042 SetHeaderValue(kPayloadLengthOffset, payload->length()); | 2096 SetHeaderValue(kPayloadLengthOffset, payload->length()); |
2043 STATIC_ASSERT(NEW_SPACE == 0); | 2097 STATIC_ASSERT(NEW_SPACE == 0); |
2044 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { | 2098 for (int i = 0; i < SerializerDeserializer::kNumberOfSpaces; i++) { |
2045 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i)); | 2099 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i)); |
2046 } | 2100 } |
2047 | 2101 |
2048 // Copy code stub keys. | 2102 // Copy code stub keys. |
2049 CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(stub_keys->begin()), | 2103 CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(stub_keys->begin()), |
2050 stub_keys_size); | 2104 stub_keys_size); |
2051 | 2105 |
2052 // Copy serialized data. | 2106 // Copy serialized data. |
2053 CopyBytes(data + kHeaderSize + stub_keys_size, payload->begin(), | 2107 CopyBytes(data + kHeaderSize + stub_keys_size, payload->begin(), |
2054 static_cast<size_t>(payload->length())); | 2108 static_cast<size_t>(payload->length())); |
2055 } | 2109 } |
2056 | 2110 |
2057 | 2111 |
2058 bool SerializedCodeData::IsSane(String* source) { | 2112 bool SerializedCodeData::IsSane(String* source) { |
2059 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && | 2113 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && |
2060 PayloadLength() >= SharedFunctionInfo::kSize; | 2114 PayloadLength() >= SharedFunctionInfo::kSize; |
2061 } | 2115 } |
2062 | 2116 |
2063 | 2117 |
2064 int SerializedCodeData::CheckSum(String* string) { | 2118 int SerializedCodeData::CheckSum(String* string) { |
2065 int checksum = Version::Hash(); | 2119 int checksum = Version::Hash(); |
2066 #ifdef DEBUG | 2120 #ifdef DEBUG |
2067 uint32_t seed = static_cast<uint32_t>(checksum); | 2121 uint32_t seed = static_cast<uint32_t>(checksum); |
2068 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); | 2122 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); |
2069 #endif // DEBUG | 2123 #endif // DEBUG |
2070 return checksum; | 2124 return checksum; |
2071 } | 2125 } |
2072 } } // namespace v8::internal | 2126 } } // namespace v8::internal |
OLD | NEW |