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 large_objects_total_size_(0) { |
| 602 for (int i = 0; i < kNumberOfReservedSpaces; i++) { |
601 reservations_[i] = kUninitializedReservation; | 603 reservations_[i] = kUninitializedReservation; |
602 } | 604 } |
603 } | 605 } |
604 | 606 |
605 | 607 |
606 void Deserializer::FlushICacheForNewCodeObjects() { | 608 void Deserializer::FlushICacheForNewCodeObjects() { |
607 PageIterator it(isolate_->heap()->code_space()); | 609 PageIterator it(isolate_->heap()->code_space()); |
608 while (it.has_next()) { | 610 while (it.has_next()) { |
609 Page* p = it.next(); | 611 Page* p = it.next(); |
610 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start()); | 612 CpuFeatures::FlushICache(p->area_start(), p->area_end() - p->area_start()); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 FlushICacheForNewCodeObjects(); | 654 FlushICacheForNewCodeObjects(); |
653 | 655 |
654 // Issue code events for newly deserialized code objects. | 656 // Issue code events for newly deserialized code objects. |
655 LOG_CODE_EVENT(isolate_, LogCodeObjects()); | 657 LOG_CODE_EVENT(isolate_, LogCodeObjects()); |
656 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); | 658 LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); |
657 } | 659 } |
658 | 660 |
659 | 661 |
660 void Deserializer::DeserializePartial(Isolate* isolate, Object** root) { | 662 void Deserializer::DeserializePartial(Isolate* isolate, Object** root) { |
661 isolate_ = isolate; | 663 isolate_ = isolate; |
662 for (int i = NEW_SPACE; i < kNumberOfSpaces; i++) { | 664 for (int i = NEW_SPACE; i < kNumberOfReservedSpaces; i++) { |
663 DCHECK(reservations_[i] != kUninitializedReservation); | 665 DCHECK(reservations_[i] != kUninitializedReservation); |
664 } | 666 } |
665 isolate_->heap()->ReserveSpace(reservations_, &high_water_[0]); | 667 Heap* heap = isolate->heap(); |
| 668 heap->lo_space()->PrepareForDeserialization(large_objects_total_size_); |
| 669 heap->ReserveSpace(reservations_, &high_water_[0]); |
666 if (external_reference_decoder_ == NULL) { | 670 if (external_reference_decoder_ == NULL) { |
667 external_reference_decoder_ = new ExternalReferenceDecoder(isolate); | 671 external_reference_decoder_ = new ExternalReferenceDecoder(isolate); |
668 } | 672 } |
669 | 673 |
670 DisallowHeapAllocation no_gc; | 674 DisallowHeapAllocation no_gc; |
671 | 675 |
672 // Keep track of the code space start and end pointers in case new | 676 // Keep track of the code space start and end pointers in case new |
673 // code objects were unserialized | 677 // code objects were unserialized |
674 OldSpace* code_space = isolate_->heap()->code_space(); | 678 OldSpace* code_space = isolate_->heap()->code_space(); |
675 Address start_address = code_space->top(); | 679 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() | 795 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() |
792 // as a (weak) root. If this root is relocated correctly, | 796 // as a (weak) root. If this root is relocated correctly, |
793 // RelinkAllocationSite() isn't necessary. | 797 // RelinkAllocationSite() isn't necessary. |
794 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); | 798 if (obj->IsAllocationSite()) RelinkAllocationSite(AllocationSite::cast(obj)); |
795 | 799 |
796 // Fix up strings from serialized user code. | 800 // Fix up strings from serialized user code. |
797 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); | 801 if (deserializing_user_code()) obj = ProcessNewObjectFromSerializedCode(obj); |
798 | 802 |
799 *write_back = obj; | 803 *write_back = obj; |
800 #ifdef DEBUG | 804 #ifdef DEBUG |
801 bool is_codespace = (space_number == CODE_SPACE); | 805 if (obj->IsCode()) { |
802 DCHECK(obj->IsCode() == is_codespace); | 806 DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE); |
| 807 } else { |
| 808 DCHECK(space_number != CODE_SPACE); |
| 809 } |
803 #endif | 810 #endif |
804 } | 811 } |
805 | 812 |
806 void Deserializer::ReadChunk(Object** current, | 813 void Deserializer::ReadChunk(Object** current, |
807 Object** limit, | 814 Object** limit, |
808 int source_space, | 815 int source_space, |
809 Address current_object_address) { | 816 Address current_object_address) { |
810 Isolate* const isolate = isolate_; | 817 Isolate* const isolate = isolate_; |
811 // Write barrier support costs around 1% in startup time. In fact there | 818 // 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, | 819 // are no new space objects in current boot snapshots, so it's not needed, |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 } \ | 925 } \ |
919 if (!current_was_incremented) { \ | 926 if (!current_was_incremented) { \ |
920 current++; \ | 927 current++; \ |
921 } \ | 928 } \ |
922 break; \ | 929 break; \ |
923 } | 930 } |
924 | 931 |
925 // This generates a case and a body for the new space (which has to do extra | 932 // 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 | 933 // write barrier handling) and handles the other spaces with 8 fall-through |
927 // cases and one body. | 934 // cases and one body. |
928 #define ALL_SPACES(where, how, within) \ | 935 #define ALL_SPACES(where, how, within) \ |
929 CASE_STATEMENT(where, how, within, NEW_SPACE) \ | 936 CASE_STATEMENT(where, how, within, NEW_SPACE) \ |
930 CASE_BODY(where, how, within, NEW_SPACE) \ | 937 CASE_BODY(where, how, within, NEW_SPACE) \ |
931 CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \ | 938 CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \ |
932 CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \ | 939 CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \ |
933 CASE_STATEMENT(where, how, within, CODE_SPACE) \ | 940 CASE_STATEMENT(where, how, within, CODE_SPACE) \ |
934 CASE_STATEMENT(where, how, within, CELL_SPACE) \ | 941 CASE_STATEMENT(where, how, within, MAP_SPACE) \ |
935 CASE_STATEMENT(where, how, within, PROPERTY_CELL_SPACE) \ | 942 CASE_STATEMENT(where, how, within, CELL_SPACE) \ |
936 CASE_STATEMENT(where, how, within, MAP_SPACE) \ | 943 CASE_STATEMENT(where, how, within, PROPERTY_CELL_SPACE) \ |
| 944 CASE_STATEMENT(where, how, within, LO_SPACE) \ |
937 CASE_BODY(where, how, within, kAnyOldSpace) | 945 CASE_BODY(where, how, within, kAnyOldSpace) |
938 | 946 |
939 #define FOUR_CASES(byte_code) \ | 947 #define FOUR_CASES(byte_code) \ |
940 case byte_code: \ | 948 case byte_code: \ |
941 case byte_code + 1: \ | 949 case byte_code + 1: \ |
942 case byte_code + 2: \ | 950 case byte_code + 2: \ |
943 case byte_code + 3: | 951 case byte_code + 3: |
944 | 952 |
945 #define SIXTEEN_CASES(byte_code) \ | 953 #define SIXTEEN_CASES(byte_code) \ |
946 FOUR_CASES(byte_code) \ | 954 FOUR_CASES(byte_code) \ |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 } | 1185 } |
1178 DCHECK_EQ(limit, current); | 1186 DCHECK_EQ(limit, current); |
1179 } | 1187 } |
1180 | 1188 |
1181 | 1189 |
1182 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) | 1190 Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) |
1183 : isolate_(isolate), | 1191 : isolate_(isolate), |
1184 sink_(sink), | 1192 sink_(sink), |
1185 external_reference_encoder_(new ExternalReferenceEncoder(isolate)), | 1193 external_reference_encoder_(new ExternalReferenceEncoder(isolate)), |
1186 root_index_wave_front_(0), | 1194 root_index_wave_front_(0), |
1187 code_address_map_(NULL) { | 1195 code_address_map_(NULL), |
| 1196 seen_large_objects_index_(0), |
| 1197 large_objects_total_size_(0) { |
1188 // The serializer is meant to be used only to generate initial heap images | 1198 // The serializer is meant to be used only to generate initial heap images |
1189 // from a context in which there is only one isolate. | 1199 // from a context in which there is only one isolate. |
1190 for (int i = 0; i <= LAST_SPACE; i++) { | 1200 for (int i = 0; i < kNumberOfReservedSpaces; i++) fullness_[i] = 0; |
1191 fullness_[i] = 0; | |
1192 } | |
1193 } | 1201 } |
1194 | 1202 |
1195 | 1203 |
1196 Serializer::~Serializer() { | 1204 Serializer::~Serializer() { |
1197 delete external_reference_encoder_; | 1205 delete external_reference_encoder_; |
1198 if (code_address_map_ != NULL) delete code_address_map_; | 1206 if (code_address_map_ != NULL) delete code_address_map_; |
1199 } | 1207 } |
1200 | 1208 |
1201 | 1209 |
1202 void StartupSerializer::SerializeStrongReferences() { | 1210 void StartupSerializer::SerializeStrongReferences() { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1317 | 1325 |
1318 // Encode the location of an already deserialized object in order to write its | 1326 // 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 | 1327 // 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 | 1328 // the start of the deserialized objects or as an offset backwards from the |
1321 // current allocation pointer. | 1329 // current allocation pointer. |
1322 void Serializer::SerializeReferenceToPreviousObject(HeapObject* heap_object, | 1330 void Serializer::SerializeReferenceToPreviousObject(HeapObject* heap_object, |
1323 HowToCode how_to_code, | 1331 HowToCode how_to_code, |
1324 WhereToPoint where_to_point, | 1332 WhereToPoint where_to_point, |
1325 int skip) { | 1333 int skip) { |
1326 int space = SpaceOfObject(heap_object); | 1334 int space = SpaceOfObject(heap_object); |
1327 int address = address_mapper_.MappedTo(heap_object); | 1335 |
1328 int offset = CurrentAllocationAddress(space) - address; | |
1329 // Shift out the bits that are always 0. | |
1330 offset >>= kObjectAlignmentBits; | |
1331 if (skip == 0) { | 1336 if (skip == 0) { |
1332 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer"); | 1337 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer"); |
1333 } else { | 1338 } else { |
1334 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space, | 1339 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space, |
1335 "BackRefSerWithSkip"); | 1340 "BackRefSerWithSkip"); |
1336 sink_->PutInt(skip, "BackRefSkipDistance"); | 1341 sink_->PutInt(skip, "BackRefSkipDistance"); |
1337 } | 1342 } |
1338 sink_->PutInt(offset, "offset"); | 1343 |
| 1344 if (space == LO_SPACE) { |
| 1345 int index = address_mapper_.MappedTo(heap_object); |
| 1346 sink_->PutInt(index, "large object index"); |
| 1347 } else { |
| 1348 int address = address_mapper_.MappedTo(heap_object); |
| 1349 int offset = CurrentAllocationAddress(space) - address; |
| 1350 // Shift out the bits that are always 0. |
| 1351 offset >>= kObjectAlignmentBits; |
| 1352 sink_->PutInt(offset, "offset"); |
| 1353 } |
1339 } | 1354 } |
1340 | 1355 |
1341 | 1356 |
1342 void StartupSerializer::SerializeObject( | 1357 void StartupSerializer::SerializeObject( |
1343 Object* o, | 1358 Object* o, |
1344 HowToCode how_to_code, | 1359 HowToCode how_to_code, |
1345 WhereToPoint where_to_point, | 1360 WhereToPoint where_to_point, |
1346 int skip) { | 1361 int skip) { |
1347 CHECK(o->IsHeapObject()); | 1362 CHECK(o->IsHeapObject()); |
1348 HeapObject* heap_object = HeapObject::cast(o); | 1363 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_) { | 1502 if (serializer_->code_address_map_) { |
1488 const char* code_name = | 1503 const char* code_name = |
1489 serializer_->code_address_map_->Lookup(object_->address()); | 1504 serializer_->code_address_map_->Lookup(object_->address()); |
1490 LOG(serializer_->isolate_, | 1505 LOG(serializer_->isolate_, |
1491 CodeNameEvent(object_->address(), sink_->Position(), code_name)); | 1506 CodeNameEvent(object_->address(), sink_->Position(), code_name)); |
1492 LOG(serializer_->isolate_, | 1507 LOG(serializer_->isolate_, |
1493 SnapshotPositionEvent(object_->address(), sink_->Position())); | 1508 SnapshotPositionEvent(object_->address(), sink_->Position())); |
1494 } | 1509 } |
1495 | 1510 |
1496 // Mark this object as already serialized. | 1511 // Mark this object as already serialized. |
1497 int offset = serializer_->Allocate(space, size); | 1512 if (space == LO_SPACE) { |
1498 serializer_->address_mapper()->AddMapping(object_, offset); | 1513 if (object_->IsCode()) { |
| 1514 sink_->PutInt(EXECUTABLE, "executable large object"); |
| 1515 } else { |
| 1516 sink_->PutInt(NOT_EXECUTABLE, "not executable large object"); |
| 1517 } |
| 1518 int index = serializer_->AllocateLargeObject(size); |
| 1519 serializer_->address_mapper()->AddMapping(object_, index); |
| 1520 } else { |
| 1521 int offset = serializer_->Allocate(space, size); |
| 1522 serializer_->address_mapper()->AddMapping(object_, offset); |
| 1523 } |
1499 | 1524 |
1500 // Serialize the map (first word of the object). | 1525 // Serialize the map (first word of the object). |
1501 serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject, 0); | 1526 serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject, 0); |
1502 | 1527 |
1503 // Serialize the rest of the object. | 1528 // Serialize the rest of the object. |
1504 CHECK_EQ(0, bytes_processed_so_far_); | 1529 CHECK_EQ(0, bytes_processed_so_far_); |
1505 bytes_processed_so_far_ = kPointerSize; | 1530 bytes_processed_so_far_ = kPointerSize; |
1506 object_->IterateBody(object_->map()->instance_type(), size, this); | 1531 object_->IterateBody(object_->map()->instance_type(), size, this); |
1507 OutputRawData(object_->address() + size); | 1532 OutputRawData(object_->address() + size); |
1508 } | 1533 } |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1740 if (object->GetHeap()->InSpace(object, s)) { | 1765 if (object->GetHeap()->InSpace(object, s)) { |
1741 DCHECK(i < kNumberOfSpaces); | 1766 DCHECK(i < kNumberOfSpaces); |
1742 return i; | 1767 return i; |
1743 } | 1768 } |
1744 } | 1769 } |
1745 UNREACHABLE(); | 1770 UNREACHABLE(); |
1746 return 0; | 1771 return 0; |
1747 } | 1772 } |
1748 | 1773 |
1749 | 1774 |
| 1775 int Serializer::AllocateLargeObject(int size) { |
| 1776 large_objects_total_size_ += size; |
| 1777 return seen_large_objects_index_++; |
| 1778 } |
| 1779 |
| 1780 |
1750 int Serializer::Allocate(int space, int size) { | 1781 int Serializer::Allocate(int space, int size) { |
1751 CHECK(space >= 0 && space < kNumberOfSpaces); | 1782 CHECK(space >= 0 && space < kNumberOfReservedSpaces); |
1752 int allocation_address = fullness_[space]; | 1783 int allocation_address = fullness_[space]; |
1753 fullness_[space] = allocation_address + size; | 1784 fullness_[space] = allocation_address + size; |
1754 return allocation_address; | 1785 return allocation_address; |
1755 } | 1786 } |
1756 | 1787 |
1757 | 1788 |
1758 int Serializer::SpaceAreaSize(int space) { | 1789 int Serializer::SpaceAreaSize(int space) { |
1759 if (space == CODE_SPACE) { | 1790 if (space == CODE_SPACE) { |
1760 return isolate_->memory_allocator()->CodePageAreaSize(); | 1791 return isolate_->memory_allocator()->CodePageAreaSize(); |
1761 } else { | 1792 } else { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1833 DCHECK(!heap_object->IsHashTable()); | 1864 DCHECK(!heap_object->IsHashTable()); |
1834 | 1865 |
1835 if (address_mapper_.IsMapped(heap_object)) { | 1866 if (address_mapper_.IsMapped(heap_object)) { |
1836 SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point, | 1867 SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point, |
1837 skip); | 1868 skip); |
1838 return; | 1869 return; |
1839 } | 1870 } |
1840 | 1871 |
1841 if (heap_object->IsCode()) { | 1872 if (heap_object->IsCode()) { |
1842 Code* code_object = Code::cast(heap_object); | 1873 Code* code_object = Code::cast(heap_object); |
| 1874 DCHECK(!code_object->is_optimized_code()); |
1843 if (code_object->kind() == Code::BUILTIN) { | 1875 if (code_object->kind() == Code::BUILTIN) { |
1844 SerializeBuiltin(code_object, how_to_code, where_to_point, skip); | 1876 SerializeBuiltin(code_object, how_to_code, where_to_point, skip); |
1845 return; | 1877 return; |
1846 } | 1878 } else if (code_object->IsCodeStubOrIC()) { |
1847 if (code_object->IsCodeStubOrIC()) { | |
1848 SerializeCodeStub(code_object, how_to_code, where_to_point, skip); | 1879 SerializeCodeStub(code_object, how_to_code, where_to_point, skip); |
1849 return; | 1880 return; |
1850 } | 1881 } |
1851 code_object->ClearInlineCaches(); | 1882 code_object->ClearInlineCaches(); |
1852 } | 1883 } |
1853 | 1884 |
1854 if (heap_object == source_) { | 1885 if (heap_object == source_) { |
1855 SerializeSourceObject(how_to_code, where_to_point, skip); | 1886 SerializeSourceObject(how_to_code, where_to_point, skip); |
1856 return; | 1887 return; |
1857 } | 1888 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1984 | 2015 |
1985 Object* root; | 2016 Object* root; |
1986 | 2017 |
1987 { | 2018 { |
1988 HandleScope scope(isolate); | 2019 HandleScope scope(isolate); |
1989 | 2020 |
1990 SerializedCodeData scd(data, *source); | 2021 SerializedCodeData scd(data, *source); |
1991 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); | 2022 SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); |
1992 Deserializer deserializer(&payload); | 2023 Deserializer deserializer(&payload); |
1993 STATIC_ASSERT(NEW_SPACE == 0); | 2024 STATIC_ASSERT(NEW_SPACE == 0); |
1994 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { | 2025 for (int i = NEW_SPACE; i < kNumberOfReservedSpaces; i++) { |
1995 deserializer.set_reservation(i, scd.GetReservation(i)); | 2026 deserializer.set_reservation(i, scd.GetReservation(i)); |
1996 } | 2027 } |
| 2028 deserializer.set_large_objects_total_size(scd.GetLargeObjectsTotalSize()); |
1997 | 2029 |
1998 // Prepare and register list of attached objects. | 2030 // Prepare and register list of attached objects. |
1999 Vector<const uint32_t> code_stub_keys = scd.CodeStubKeys(); | 2031 Vector<const uint32_t> code_stub_keys = scd.CodeStubKeys(); |
2000 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New( | 2032 Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New( |
2001 code_stub_keys.length() + kCodeStubsBaseIndex); | 2033 code_stub_keys.length() + kCodeStubsBaseIndex); |
2002 attached_objects[kSourceObjectIndex] = source; | 2034 attached_objects[kSourceObjectIndex] = source; |
2003 for (int i = 0; i < code_stub_keys.length(); i++) { | 2035 for (int i = 0; i < code_stub_keys.length(); i++) { |
2004 attached_objects[i + kCodeStubsBaseIndex] = | 2036 attached_objects[i + kCodeStubsBaseIndex] = |
2005 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked(); | 2037 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked(); |
2006 } | 2038 } |
(...skipping 26 matching lines...) Expand all Loading... |
2033 // Allocate backing store and create result data. | 2065 // Allocate backing store and create result data. |
2034 byte* data = NewArray<byte>(data_length); | 2066 byte* data = NewArray<byte>(data_length); |
2035 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); | 2067 DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)); |
2036 script_data_ = new ScriptData(data, data_length); | 2068 script_data_ = new ScriptData(data, data_length); |
2037 script_data_->AcquireDataOwnership(); | 2069 script_data_->AcquireDataOwnership(); |
2038 | 2070 |
2039 // Set header values. | 2071 // Set header values. |
2040 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); | 2072 SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); |
2041 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); | 2073 SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); |
2042 SetHeaderValue(kPayloadLengthOffset, payload->length()); | 2074 SetHeaderValue(kPayloadLengthOffset, payload->length()); |
| 2075 SetHeaderValue(kLargeObjectsTotalSizeOffset, cs->large_objects_total_size()); |
2043 STATIC_ASSERT(NEW_SPACE == 0); | 2076 STATIC_ASSERT(NEW_SPACE == 0); |
2044 for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { | 2077 for (int i = 0; i < SerializerDeserializer::kNumberOfReservedSpaces; i++) { |
2045 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i)); | 2078 SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i)); |
2046 } | 2079 } |
2047 | 2080 |
2048 // Copy code stub keys. | 2081 // Copy code stub keys. |
2049 CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(stub_keys->begin()), | 2082 CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(stub_keys->begin()), |
2050 stub_keys_size); | 2083 stub_keys_size); |
2051 | 2084 |
2052 // Copy serialized data. | 2085 // Copy serialized data. |
2053 CopyBytes(data + kHeaderSize + stub_keys_size, payload->begin(), | 2086 CopyBytes(data + kHeaderSize + stub_keys_size, payload->begin(), |
2054 static_cast<size_t>(payload->length())); | 2087 static_cast<size_t>(payload->length())); |
2055 } | 2088 } |
2056 | 2089 |
2057 | 2090 |
2058 bool SerializedCodeData::IsSane(String* source) { | 2091 bool SerializedCodeData::IsSane(String* source) { |
2059 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && | 2092 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && |
2060 PayloadLength() >= SharedFunctionInfo::kSize; | 2093 PayloadLength() >= SharedFunctionInfo::kSize; |
2061 } | 2094 } |
2062 | 2095 |
2063 | 2096 |
2064 int SerializedCodeData::CheckSum(String* string) { | 2097 int SerializedCodeData::CheckSum(String* string) { |
2065 int checksum = Version::Hash(); | 2098 int checksum = Version::Hash(); |
2066 #ifdef DEBUG | 2099 #ifdef DEBUG |
2067 uint32_t seed = static_cast<uint32_t>(checksum); | 2100 uint32_t seed = static_cast<uint32_t>(checksum); |
2068 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); | 2101 checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed)); |
2069 #endif // DEBUG | 2102 #endif // DEBUG |
2070 return checksum; | 2103 return checksum; |
2071 } | 2104 } |
2072 } } // namespace v8::internal | 2105 } } // namespace v8::internal |
OLD | NEW |