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 789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
800 } | 800 } |
801 return obj; | 801 return obj; |
802 } | 802 } |
803 | 803 |
804 | 804 |
805 // This routine writes the new object into the pointer provided and then | 805 // 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. | 806 // 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 | 807 // 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 | 808 // 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. | 809 // time we need to use it to mark the space at the end of a page free. |
810 void Deserializer::ReadObject(int space_number, | 810 void Deserializer::ReadObject(int space_number, Object** write_back, |
811 Object** write_back) { | 811 bool double_align) { |
812 int size = source_->GetInt() << kObjectAlignmentBits; | 812 int size = source_->GetInt() << kObjectAlignmentBits; |
813 Address address = Allocate(space_number, size); | 813 Address address; |
814 HeapObject* obj = HeapObject::FromAddress(address); | 814 HeapObject* obj; |
815 if (double_align) { | |
816 DCHECK_NE(LO_SPACE, space_number); | |
817 address = Allocate(space_number, size + kPointerSize); | |
rmcilroy
2014/11/26 17:44:40
You should only need to add kPointerSize if not a
Yang
2014/11/26 18:59:49
I think this entire if-branch can be omitted for 6
rmcilroy
2014/11/26 19:24:46
agreed.
| |
818 obj = isolate_->heap()->DoubleAlignForDeserialization( | |
819 HeapObject::FromAddress(address), size + kPointerSize); | |
820 address = obj->address(); | |
821 } else { | |
822 address = Allocate(space_number, size); | |
823 obj = HeapObject::FromAddress(address); | |
824 } | |
815 isolate_->heap()->OnAllocationEvent(obj, size); | 825 isolate_->heap()->OnAllocationEvent(obj, size); |
816 Object** current = reinterpret_cast<Object**>(address); | 826 Object** current = reinterpret_cast<Object**>(address); |
817 Object** limit = current + (size >> kPointerSizeLog2); | 827 Object** limit = current + (size >> kPointerSizeLog2); |
818 if (FLAG_log_snapshot_positions) { | 828 if (FLAG_log_snapshot_positions) { |
819 LOG(isolate_, SnapshotPositionEvent(address, source_->position())); | 829 LOG(isolate_, SnapshotPositionEvent(address, source_->position())); |
820 } | 830 } |
821 ReadData(current, limit, space_number, address); | 831 ReadData(current, limit, space_number, address); |
822 | 832 |
823 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() | 833 // TODO(mvstanton): consider treating the heap()->allocation_sites_list() |
824 // as a (weak) root. If this root is relocated correctly, | 834 // as a (weak) root. If this root is relocated correctly, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
887 Isolate* const isolate = isolate_; | 897 Isolate* const isolate = isolate_; |
888 // Write barrier support costs around 1% in startup time. In fact there | 898 // Write barrier support costs around 1% in startup time. In fact there |
889 // are no new space objects in current boot snapshots, so it's not needed, | 899 // are no new space objects in current boot snapshots, so it's not needed, |
890 // but that may change. | 900 // but that may change. |
891 bool write_barrier_needed = (current_object_address != NULL && | 901 bool write_barrier_needed = (current_object_address != NULL && |
892 source_space != NEW_SPACE && | 902 source_space != NEW_SPACE && |
893 source_space != CELL_SPACE && | 903 source_space != CELL_SPACE && |
894 source_space != PROPERTY_CELL_SPACE && | 904 source_space != PROPERTY_CELL_SPACE && |
895 source_space != CODE_SPACE && | 905 source_space != CODE_SPACE && |
896 source_space != OLD_DATA_SPACE); | 906 source_space != OLD_DATA_SPACE); |
907 bool double_align_next_object = false; | |
897 while (current < limit) { | 908 while (current < limit) { |
898 int data = source_->Get(); | 909 int data = source_->Get(); |
899 switch (data) { | 910 switch (data) { |
900 #define CASE_STATEMENT(where, how, within, space_number) \ | 911 #define CASE_STATEMENT(where, how, within, space_number) \ |
901 case where + how + within + space_number: \ | 912 case where + how + within + space_number: \ |
902 STATIC_ASSERT((where & ~kPointedToMask) == 0); \ | 913 STATIC_ASSERT((where & ~kPointedToMask) == 0); \ |
903 STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \ | 914 STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \ |
904 STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \ | 915 STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \ |
905 STATIC_ASSERT((space_number & ~kSpaceMask) == 0); | 916 STATIC_ASSERT((space_number & ~kSpaceMask) == 0); |
906 | 917 |
907 #define CASE_BODY(where, how, within, space_number_if_any) \ | 918 #define CASE_BODY(where, how, within, space_number_if_any) \ |
908 { \ | 919 { \ |
909 bool emit_write_barrier = false; \ | 920 bool emit_write_barrier = false; \ |
910 bool current_was_incremented = false; \ | 921 bool current_was_incremented = false; \ |
911 int space_number = space_number_if_any == kAnyOldSpace \ | 922 int space_number = space_number_if_any == kAnyOldSpace \ |
912 ? (data & kSpaceMask) \ | 923 ? (data & kSpaceMask) \ |
913 : space_number_if_any; \ | 924 : space_number_if_any; \ |
925 DCHECK(!double_align_next_object || where == kNewObject); \ | |
914 if (where == kNewObject && how == kPlain && within == kStartOfObject) { \ | 926 if (where == kNewObject && how == kPlain && within == kStartOfObject) { \ |
915 ReadObject(space_number, current); \ | 927 ReadObject(space_number, current, double_align_next_object); \ |
928 double_align_next_object = false; \ | |
916 emit_write_barrier = (space_number == NEW_SPACE); \ | 929 emit_write_barrier = (space_number == NEW_SPACE); \ |
917 } else { \ | 930 } else { \ |
918 Object* new_object = NULL; /* May not be a real Object pointer. */ \ | 931 Object* new_object = NULL; /* May not be a real Object pointer. */ \ |
919 if (where == kNewObject) { \ | 932 if (where == kNewObject) { \ |
920 ReadObject(space_number, &new_object); \ | 933 ReadObject(space_number, &new_object, double_align_next_object); \ |
934 double_align_next_object = false; \ | |
921 } else if (where == kRootArray) { \ | 935 } else if (where == kRootArray) { \ |
922 int root_id = source_->GetInt(); \ | 936 int root_id = source_->GetInt(); \ |
923 new_object = isolate->heap()->roots_array_start()[root_id]; \ | 937 new_object = isolate->heap()->roots_array_start()[root_id]; \ |
924 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ | 938 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ |
925 } else if (where == kPartialSnapshotCache) { \ | 939 } else if (where == kPartialSnapshotCache) { \ |
926 int cache_index = source_->GetInt(); \ | 940 int cache_index = source_->GetInt(); \ |
927 new_object = isolate->serialize_partial_snapshot_cache()[cache_index]; \ | 941 new_object = isolate->serialize_partial_snapshot_cache()[cache_index]; \ |
928 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ | 942 emit_write_barrier = isolate->heap()->InNewSpace(new_object); \ |
929 } else if (where == kExternalReference) { \ | 943 } else if (where == kExternalReference) { \ |
930 int skip = source_->GetInt(); \ | 944 int skip = source_->GetInt(); \ |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1231 int index = source_->Get(); | 1245 int index = source_->Get(); |
1232 Vector<const char> source_vector = Natives::GetRawScriptSource(index); | 1246 Vector<const char> source_vector = Natives::GetRawScriptSource(index); |
1233 NativesExternalStringResource* resource = | 1247 NativesExternalStringResource* resource = |
1234 new NativesExternalStringResource(isolate->bootstrapper(), | 1248 new NativesExternalStringResource(isolate->bootstrapper(), |
1235 source_vector.start(), | 1249 source_vector.start(), |
1236 source_vector.length()); | 1250 source_vector.length()); |
1237 *current++ = reinterpret_cast<Object*>(resource); | 1251 *current++ = reinterpret_cast<Object*>(resource); |
1238 break; | 1252 break; |
1239 } | 1253 } |
1240 | 1254 |
1255 #ifndef V8_HOST_ARCH_64_BIT | |
1256 case kDoubleAlignPrefix: { | |
1257 DCHECK(!double_align_next_object); | |
1258 double_align_next_object = true; | |
1259 break; | |
1260 } | |
1261 #endif | |
1262 | |
1241 case kSynchronize: { | 1263 case kSynchronize: { |
1242 // If we get here then that indicates that you have a mismatch between | 1264 // If we get here then that indicates that you have a mismatch between |
1243 // the number of GC roots when serializing and deserializing. | 1265 // the number of GC roots when serializing and deserializing. |
1244 UNREACHABLE(); | 1266 UNREACHABLE(); |
1245 } | 1267 } |
1246 | 1268 |
1247 default: | 1269 default: |
1248 UNREACHABLE(); | 1270 UNREACHABLE(); |
1249 } | 1271 } |
1250 } | 1272 } |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1542 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); | 1564 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); |
1543 } | 1565 } |
1544 // Object has not yet been serialized. Serialize it here. | 1566 // Object has not yet been serialized. Serialize it here. |
1545 ObjectSerializer serializer(this, obj, sink_, how_to_code, where_to_point); | 1567 ObjectSerializer serializer(this, obj, sink_, how_to_code, where_to_point); |
1546 serializer.Serialize(); | 1568 serializer.Serialize(); |
1547 } | 1569 } |
1548 | 1570 |
1549 | 1571 |
1550 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space, | 1572 void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space, |
1551 int size, Map* map) { | 1573 int size, Map* map) { |
1574 int reserved_size = size; | |
1575 // Objects on the large object space are always double-aligned. | |
1576 if (space != LO_SPACE && object_->NeedsToEnsureDoubleAlignment()) { | |
1577 sink_->Put(kDoubleAlignPrefix, "double align next object"); | |
1578 // Add wriggle room for double alignment padding. | |
1579 reserved_size += kPointerSize; | |
1580 } | |
1581 | |
1552 sink_->Put(kNewObject + reference_representation_ + space, | 1582 sink_->Put(kNewObject + reference_representation_ + space, |
1553 "ObjectSerialization"); | 1583 "ObjectSerialization"); |
1554 sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); | 1584 sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); |
1555 | 1585 |
1556 if (serializer_->code_address_map_) { | 1586 if (serializer_->code_address_map_) { |
1557 const char* code_name = | 1587 const char* code_name = |
1558 serializer_->code_address_map_->Lookup(object_->address()); | 1588 serializer_->code_address_map_->Lookup(object_->address()); |
1559 LOG(serializer_->isolate_, | 1589 LOG(serializer_->isolate_, |
1560 CodeNameEvent(object_->address(), sink_->Position(), code_name)); | 1590 CodeNameEvent(object_->address(), sink_->Position(), code_name)); |
1561 LOG(serializer_->isolate_, | 1591 LOG(serializer_->isolate_, |
1562 SnapshotPositionEvent(object_->address(), sink_->Position())); | 1592 SnapshotPositionEvent(object_->address(), sink_->Position())); |
1563 } | 1593 } |
1564 | 1594 |
1565 // Mark this object as already serialized. | 1595 // Mark this object as already serialized. |
1566 BackReference back_reference; | 1596 BackReference back_reference; |
1567 if (space == LO_SPACE) { | 1597 if (space == LO_SPACE) { |
1568 if (object_->IsCode()) { | 1598 if (object_->IsCode()) { |
1569 sink_->Put(EXECUTABLE, "executable large object"); | 1599 sink_->Put(EXECUTABLE, "executable large object"); |
1570 } else { | 1600 } else { |
1571 sink_->Put(NOT_EXECUTABLE, "not executable large object"); | 1601 sink_->Put(NOT_EXECUTABLE, "not executable large object"); |
1572 } | 1602 } |
1573 back_reference = serializer_->AllocateLargeObject(size); | 1603 back_reference = serializer_->AllocateLargeObject(size); |
1574 } else { | 1604 } else { |
1575 back_reference = serializer_->Allocate(space, size); | 1605 back_reference = serializer_->Allocate(space, reserved_size); |
1576 } | 1606 } |
1577 serializer_->back_reference_map()->Add(object_, back_reference); | 1607 serializer_->back_reference_map()->Add(object_, back_reference); |
1578 | 1608 |
1579 // Serialize the map (first word of the object). | 1609 // Serialize the map (first word of the object). |
1580 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0); | 1610 serializer_->SerializeObject(map, kPlain, kStartOfObject, 0); |
1581 } | 1611 } |
1582 | 1612 |
1583 | 1613 |
1584 void Serializer::ObjectSerializer::SerializeExternalString() { | 1614 void Serializer::ObjectSerializer::SerializeExternalString() { |
1585 // Instead of serializing this as an external string, we serialize | 1615 // Instead of serializing this as an external string, we serialize |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1911 | 1941 |
1912 BackReference Serializer::AllocateLargeObject(int size) { | 1942 BackReference Serializer::AllocateLargeObject(int size) { |
1913 // Large objects are allocated one-by-one when deserializing. We do not | 1943 // Large objects are allocated one-by-one when deserializing. We do not |
1914 // have to keep track of multiple chunks. | 1944 // have to keep track of multiple chunks. |
1915 large_objects_total_size_ += size; | 1945 large_objects_total_size_ += size; |
1916 return BackReference::LargeObjectReference(seen_large_objects_index_++); | 1946 return BackReference::LargeObjectReference(seen_large_objects_index_++); |
1917 } | 1947 } |
1918 | 1948 |
1919 | 1949 |
1920 BackReference Serializer::Allocate(AllocationSpace space, int size) { | 1950 BackReference Serializer::Allocate(AllocationSpace space, int size) { |
1921 CHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); | 1951 DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces); |
1922 DCHECK(size > 0 && size <= static_cast<int>(max_chunk_size(space))); | 1952 DCHECK(size > 0 && size <= static_cast<int>(max_chunk_size(space))); |
1923 uint32_t new_chunk_size = pending_chunk_[space] + size; | 1953 uint32_t new_chunk_size = pending_chunk_[space] + size; |
1924 if (new_chunk_size > max_chunk_size(space)) { | 1954 if (new_chunk_size > max_chunk_size(space)) { |
1925 // The new chunk size would not fit onto a single page. Complete the | 1955 // The new chunk size would not fit onto a single page. Complete the |
1926 // current chunk and start a new one. | 1956 // current chunk and start a new one. |
1927 completed_chunks_[space].Add(pending_chunk_[space]); | 1957 completed_chunks_[space].Add(pending_chunk_[space]); |
1928 pending_chunk_[space] = 0; | 1958 pending_chunk_[space] = 0; |
1929 new_chunk_size = size; | 1959 new_chunk_size = size; |
1930 } | 1960 } |
1931 uint32_t offset = pending_chunk_[space]; | 1961 uint32_t offset = pending_chunk_[space]; |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2321 bool SerializedCodeData::IsSane(String* source) { | 2351 bool SerializedCodeData::IsSane(String* source) { |
2322 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && | 2352 return GetHeaderValue(kCheckSumOffset) == CheckSum(source) && |
2323 PayloadLength() >= SharedFunctionInfo::kSize; | 2353 PayloadLength() >= SharedFunctionInfo::kSize; |
2324 } | 2354 } |
2325 | 2355 |
2326 | 2356 |
2327 int SerializedCodeData::CheckSum(String* string) { | 2357 int SerializedCodeData::CheckSum(String* string) { |
2328 return Version::Hash() ^ string->length(); | 2358 return Version::Hash() ^ string->length(); |
2329 } | 2359 } |
2330 } } // namespace v8::internal | 2360 } } // namespace v8::internal |
OLD | NEW |