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 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 } | 746 } |
747 isolate_->heap()->set_allocation_sites_list(site); | 747 isolate_->heap()->set_allocation_sites_list(site); |
748 } else if (obj->IsCode()) { | 748 } else if (obj->IsCode()) { |
749 // We flush all code pages after deserializing the startup snapshot. In that | 749 // We flush all code pages after deserializing the startup snapshot. In that |
750 // case, we only need to remember code objects in the large object space. | 750 // case, we only need to remember code objects in the large object space. |
751 // When deserializing user code, remember each individual code object. | 751 // When deserializing user code, remember each individual code object. |
752 if (deserializing_user_code() || space == LO_SPACE) { | 752 if (deserializing_user_code() || space == LO_SPACE) { |
753 new_code_objects_.Add(Code::cast(obj)); | 753 new_code_objects_.Add(Code::cast(obj)); |
754 } | 754 } |
755 } | 755 } |
756 // Check alignment. | |
757 DCHECK_EQ(0, Heap::GetFillToAlign(obj->address(), obj->RequiredAlignment())); | |
758 return obj; | 756 return obj; |
759 } | 757 } |
760 | 758 |
761 | 759 |
762 HeapObject* Deserializer::GetBackReferencedObject(int space) { | 760 HeapObject* Deserializer::GetBackReferencedObject(int space) { |
763 HeapObject* obj; | 761 HeapObject* obj; |
764 BackReference back_reference(source_.GetInt()); | 762 BackReference back_reference(source_.GetInt()); |
765 if (space == LO_SPACE) { | 763 if (space == LO_SPACE) { |
766 CHECK(back_reference.chunk_index() == 0); | 764 CHECK(back_reference.chunk_index() == 0); |
767 uint32_t index = back_reference.large_object_index(); | 765 uint32_t index = back_reference.large_object_index(); |
768 obj = deserialized_large_objects_[index]; | 766 obj = deserialized_large_objects_[index]; |
769 } else { | 767 } else { |
770 DCHECK(space < kNumberOfPreallocatedSpaces); | 768 DCHECK(space < kNumberOfPreallocatedSpaces); |
771 uint32_t chunk_index = back_reference.chunk_index(); | 769 uint32_t chunk_index = back_reference.chunk_index(); |
772 DCHECK_LE(chunk_index, current_chunk_[space]); | 770 DCHECK_LE(chunk_index, current_chunk_[space]); |
773 uint32_t chunk_offset = back_reference.chunk_offset(); | 771 uint32_t chunk_offset = back_reference.chunk_offset(); |
774 Address address = reservations_[space][chunk_index].start + chunk_offset; | 772 obj = HeapObject::FromAddress(reservations_[space][chunk_index].start + |
775 if (next_alignment_ != kWordAligned) { | 773 chunk_offset); |
776 int padding = Heap::GetFillToAlign(address, next_alignment_); | |
777 next_alignment_ = kWordAligned; | |
778 DCHECK(padding == 0 || HeapObject::FromAddress(address)->IsFiller()); | |
779 address += padding; | |
780 } | |
781 obj = HeapObject::FromAddress(address); | |
782 } | 774 } |
783 if (deserializing_user_code() && obj->IsInternalizedString()) { | 775 if (deserializing_user_code() && obj->IsInternalizedString()) { |
784 obj = String::cast(obj)->GetForwardedInternalizedString(); | 776 obj = String::cast(obj)->GetForwardedInternalizedString(); |
785 } | 777 } |
786 hot_objects_.Add(obj); | 778 hot_objects_.Add(obj); |
787 return obj; | 779 return obj; |
788 } | 780 } |
789 | 781 |
790 | 782 |
791 // This routine writes the new object into the pointer provided and then | 783 // This routine writes the new object into the pointer provided and then |
792 // returns true if the new object was in young space and false otherwise. | 784 // returns true if the new object was in young space and false otherwise. |
793 // The reason for this strange interface is that otherwise the object is | 785 // The reason for this strange interface is that otherwise the object is |
794 // written very late, which means the FreeSpace map is not set up by the | 786 // written very late, which means the FreeSpace map is not set up by the |
795 // time we need to use it to mark the space at the end of a page free. | 787 // time we need to use it to mark the space at the end of a page free. |
796 void Deserializer::ReadObject(int space_number, Object** write_back) { | 788 void Deserializer::ReadObject(int space_number, Object** write_back) { |
797 Address address; | 789 Address address; |
798 HeapObject* obj; | 790 HeapObject* obj; |
799 int size = source_.GetInt() << kObjectAlignmentBits; | 791 int next_int = source_.GetInt(); |
800 | 792 |
801 if (next_alignment_ != kWordAligned) { | 793 bool double_align = false; |
802 int reserved = size + Heap::GetMaximumFillToAlign(next_alignment_); | 794 #ifndef V8_HOST_ARCH_64_BIT |
803 address = Allocate(space_number, reserved); | 795 double_align = next_int == kDoubleAlignmentSentinel; |
804 obj = HeapObject::FromAddress(address); | 796 if (double_align) next_int = source_.GetInt(); |
805 // If one of the following assertions fails, then we are deserializing an | 797 #endif |
806 // aligned object when the filler maps have not been deserialized yet. | 798 |
807 // We require filler maps as padding to align the object. | 799 DCHECK_NE(kDoubleAlignmentSentinel, next_int); |
808 Heap* heap = isolate_->heap(); | 800 int size = next_int << kObjectAlignmentBits; |
809 DCHECK(heap->free_space_map()->IsMap()); | 801 int reserved_size = size + (double_align ? kPointerSize : 0); |
810 DCHECK(heap->one_pointer_filler_map()->IsMap()); | 802 address = Allocate(space_number, reserved_size); |
811 DCHECK(heap->two_pointer_filler_map()->IsMap()); | 803 obj = HeapObject::FromAddress(address); |
812 obj = heap->AlignWithFiller(obj, size, reserved, next_alignment_); | 804 if (double_align) { |
| 805 obj = isolate_->heap()->DoubleAlignForDeserialization(obj, reserved_size); |
813 address = obj->address(); | 806 address = obj->address(); |
814 next_alignment_ = kWordAligned; | |
815 } else { | |
816 address = Allocate(space_number, size); | |
817 obj = HeapObject::FromAddress(address); | |
818 } | 807 } |
819 | 808 |
820 isolate_->heap()->OnAllocationEvent(obj, size); | 809 isolate_->heap()->OnAllocationEvent(obj, size); |
821 Object** current = reinterpret_cast<Object**>(address); | 810 Object** current = reinterpret_cast<Object**>(address); |
822 Object** limit = current + (size >> kPointerSizeLog2); | 811 Object** limit = current + (size >> kPointerSizeLog2); |
823 if (FLAG_log_snapshot_positions) { | 812 if (FLAG_log_snapshot_positions) { |
824 LOG(isolate_, SnapshotPositionEvent(address, source_.position())); | 813 LOG(isolate_, SnapshotPositionEvent(address, source_.position())); |
825 } | 814 } |
826 | 815 |
827 if (ReadData(current, limit, space_number, address)) { | 816 if (ReadData(current, limit, space_number, address)) { |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 case byte_code + 1: \ | 991 case byte_code + 1: \ |
1003 case byte_code + 2: \ | 992 case byte_code + 2: \ |
1004 case byte_code + 3: | 993 case byte_code + 3: |
1005 | 994 |
1006 #define SIXTEEN_CASES(byte_code) \ | 995 #define SIXTEEN_CASES(byte_code) \ |
1007 FOUR_CASES(byte_code) \ | 996 FOUR_CASES(byte_code) \ |
1008 FOUR_CASES(byte_code + 4) \ | 997 FOUR_CASES(byte_code + 4) \ |
1009 FOUR_CASES(byte_code + 8) \ | 998 FOUR_CASES(byte_code + 8) \ |
1010 FOUR_CASES(byte_code + 12) | 999 FOUR_CASES(byte_code + 12) |
1011 | 1000 |
1012 #define SINGLE_CASE(where, how, within, space) \ | |
1013 CASE_STATEMENT(where, how, within, space) \ | |
1014 CASE_BODY(where, how, within, space) | |
1015 | |
1016 // Deserialize a new object and write a pointer to it to the current | 1001 // Deserialize a new object and write a pointer to it to the current |
1017 // object. | 1002 // object. |
1018 ALL_SPACES(kNewObject, kPlain, kStartOfObject) | 1003 ALL_SPACES(kNewObject, kPlain, kStartOfObject) |
1019 // Support for direct instruction pointers in functions. It's an inner | 1004 // Support for direct instruction pointers in functions. It's an inner |
1020 // pointer because it points at the entry point, not at the start of the | 1005 // pointer because it points at the entry point, not at the start of the |
1021 // code object. | 1006 // code object. |
1022 SINGLE_CASE(kNewObject, kPlain, kInnerPointer, CODE_SPACE) | 1007 CASE_STATEMENT(kNewObject, kPlain, kInnerPointer, CODE_SPACE) |
| 1008 CASE_BODY(kNewObject, kPlain, kInnerPointer, CODE_SPACE) |
1023 // Deserialize a new code object and write a pointer to its first | 1009 // Deserialize a new code object and write a pointer to its first |
1024 // instruction to the current code object. | 1010 // instruction to the current code object. |
1025 ALL_SPACES(kNewObject, kFromCode, kInnerPointer) | 1011 ALL_SPACES(kNewObject, kFromCode, kInnerPointer) |
1026 // Find a recently deserialized object using its offset from the current | 1012 // Find a recently deserialized object using its offset from the current |
1027 // allocation point and write a pointer to it to the current object. | 1013 // allocation point and write a pointer to it to the current object. |
1028 ALL_SPACES(kBackref, kPlain, kStartOfObject) | 1014 ALL_SPACES(kBackref, kPlain, kStartOfObject) |
1029 ALL_SPACES(kBackrefWithSkip, kPlain, kStartOfObject) | 1015 ALL_SPACES(kBackrefWithSkip, kPlain, kStartOfObject) |
1030 #if defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64) || \ | 1016 #if defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64) || \ |
1031 defined(V8_TARGET_ARCH_PPC) || V8_EMBEDDED_CONSTANT_POOL | 1017 defined(V8_TARGET_ARCH_PPC) || V8_EMBEDDED_CONSTANT_POOL |
1032 // Deserialize a new object from pointer found in code and write | 1018 // Deserialize a new object from pointer found in code and write |
(...skipping 10 matching lines...) Expand all Loading... |
1043 // Find a recently deserialized code object using its offset from the | 1029 // Find a recently deserialized code object using its offset from the |
1044 // current allocation point and write a pointer to its first instruction | 1030 // current allocation point and write a pointer to its first instruction |
1045 // to the current code object or the instruction pointer in a function | 1031 // to the current code object or the instruction pointer in a function |
1046 // object. | 1032 // object. |
1047 ALL_SPACES(kBackref, kFromCode, kInnerPointer) | 1033 ALL_SPACES(kBackref, kFromCode, kInnerPointer) |
1048 ALL_SPACES(kBackrefWithSkip, kFromCode, kInnerPointer) | 1034 ALL_SPACES(kBackrefWithSkip, kFromCode, kInnerPointer) |
1049 ALL_SPACES(kBackref, kPlain, kInnerPointer) | 1035 ALL_SPACES(kBackref, kPlain, kInnerPointer) |
1050 ALL_SPACES(kBackrefWithSkip, kPlain, kInnerPointer) | 1036 ALL_SPACES(kBackrefWithSkip, kPlain, kInnerPointer) |
1051 // Find an object in the roots array and write a pointer to it to the | 1037 // Find an object in the roots array and write a pointer to it to the |
1052 // current object. | 1038 // current object. |
1053 SINGLE_CASE(kRootArray, kPlain, kStartOfObject, 0) | 1039 CASE_STATEMENT(kRootArray, kPlain, kStartOfObject, 0) |
| 1040 CASE_BODY(kRootArray, kPlain, kStartOfObject, 0) |
1054 #if defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64) || \ | 1041 #if defined(V8_TARGET_ARCH_MIPS) || defined(V8_TARGET_ARCH_MIPS64) || \ |
1055 defined(V8_TARGET_ARCH_PPC) || V8_EMBEDDED_CONSTANT_POOL | 1042 defined(V8_TARGET_ARCH_PPC) || V8_EMBEDDED_CONSTANT_POOL |
1056 // Find an object in the roots array and write a pointer to it to in code. | 1043 // Find an object in the roots array and write a pointer to it to in code. |
1057 SINGLE_CASE(kRootArray, kFromCode, kStartOfObject, 0) | 1044 CASE_STATEMENT(kRootArray, kFromCode, kStartOfObject, 0) |
| 1045 CASE_BODY(kRootArray, kFromCode, kStartOfObject, 0) |
1058 #endif | 1046 #endif |
1059 // Find an object in the partial snapshots cache and write a pointer to it | 1047 // Find an object in the partial snapshots cache and write a pointer to it |
1060 // to the current object. | 1048 // to the current object. |
1061 SINGLE_CASE(kPartialSnapshotCache, kPlain, kStartOfObject, 0) | 1049 CASE_STATEMENT(kPartialSnapshotCache, kPlain, kStartOfObject, 0) |
| 1050 CASE_BODY(kPartialSnapshotCache, kPlain, kStartOfObject, 0) |
1062 // Find an code entry in the partial snapshots cache and | 1051 // Find an code entry in the partial snapshots cache and |
1063 // write a pointer to it to the current object. | 1052 // write a pointer to it to the current object. |
1064 SINGLE_CASE(kPartialSnapshotCache, kPlain, kInnerPointer, 0) | 1053 CASE_STATEMENT(kPartialSnapshotCache, kPlain, kInnerPointer, 0) |
| 1054 CASE_BODY(kPartialSnapshotCache, kPlain, kInnerPointer, 0) |
1065 // Find an external reference and write a pointer to it to the current | 1055 // Find an external reference and write a pointer to it to the current |
1066 // object. | 1056 // object. |
1067 SINGLE_CASE(kExternalReference, kPlain, kStartOfObject, 0) | 1057 CASE_STATEMENT(kExternalReference, kPlain, kStartOfObject, 0) |
| 1058 CASE_BODY(kExternalReference, kPlain, kStartOfObject, 0) |
1068 // Find an external reference and write a pointer to it in the current | 1059 // Find an external reference and write a pointer to it in the current |
1069 // code object. | 1060 // code object. |
1070 SINGLE_CASE(kExternalReference, kFromCode, kStartOfObject, 0) | 1061 CASE_STATEMENT(kExternalReference, kFromCode, kStartOfObject, 0) |
| 1062 CASE_BODY(kExternalReference, kFromCode, kStartOfObject, 0) |
1071 // Find an object in the attached references and write a pointer to it to | 1063 // Find an object in the attached references and write a pointer to it to |
1072 // the current object. | 1064 // the current object. |
1073 SINGLE_CASE(kAttachedReference, kPlain, kStartOfObject, 0) | 1065 CASE_STATEMENT(kAttachedReference, kPlain, kStartOfObject, 0) |
1074 SINGLE_CASE(kAttachedReference, kPlain, kInnerPointer, 0) | 1066 CASE_BODY(kAttachedReference, kPlain, kStartOfObject, 0) |
1075 SINGLE_CASE(kAttachedReference, kFromCode, kInnerPointer, 0) | 1067 CASE_STATEMENT(kAttachedReference, kPlain, kInnerPointer, 0) |
| 1068 CASE_BODY(kAttachedReference, kPlain, kInnerPointer, 0) |
| 1069 CASE_STATEMENT(kAttachedReference, kFromCode, kInnerPointer, 0) |
| 1070 CASE_BODY(kAttachedReference, kFromCode, kInnerPointer, 0) |
1076 // Find a builtin and write a pointer to it to the current object. | 1071 // Find a builtin and write a pointer to it to the current object. |
1077 SINGLE_CASE(kBuiltin, kPlain, kStartOfObject, 0) | 1072 CASE_STATEMENT(kBuiltin, kPlain, kStartOfObject, 0) |
1078 SINGLE_CASE(kBuiltin, kPlain, kInnerPointer, 0) | 1073 CASE_BODY(kBuiltin, kPlain, kStartOfObject, 0) |
1079 SINGLE_CASE(kBuiltin, kFromCode, kInnerPointer, 0) | 1074 CASE_STATEMENT(kBuiltin, kPlain, kInnerPointer, 0) |
| 1075 CASE_BODY(kBuiltin, kPlain, kInnerPointer, 0) |
| 1076 CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0) |
| 1077 CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0) |
1080 | 1078 |
1081 #undef CASE_STATEMENT | 1079 #undef CASE_STATEMENT |
1082 #undef CASE_BODY | 1080 #undef CASE_BODY |
1083 #undef ALL_SPACES | 1081 #undef ALL_SPACES |
1084 | 1082 |
1085 case kSkip: { | 1083 case kSkip: { |
1086 int size = source_.GetInt(); | 1084 int size = source_.GetInt(); |
1087 current = reinterpret_cast<Object**>( | 1085 current = reinterpret_cast<Object**>( |
1088 reinterpret_cast<intptr_t>(current) + size); | 1086 reinterpret_cast<intptr_t>(current) + size); |
1089 break; | 1087 break; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1164 } | 1162 } |
1165 | 1163 |
1166 case kVariableRepeat: { | 1164 case kVariableRepeat: { |
1167 int repeats = source_.GetInt(); | 1165 int repeats = source_.GetInt(); |
1168 Object* object = current[-1]; | 1166 Object* object = current[-1]; |
1169 DCHECK(!isolate->heap()->InNewSpace(object)); | 1167 DCHECK(!isolate->heap()->InNewSpace(object)); |
1170 for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object); | 1168 for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object); |
1171 break; | 1169 break; |
1172 } | 1170 } |
1173 | 1171 |
1174 case kAlignmentPrefix: | |
1175 case kAlignmentPrefix + 1: | |
1176 case kAlignmentPrefix + 2: { | |
1177 DCHECK_EQ(kWordAligned, next_alignment_); | |
1178 next_alignment_ = | |
1179 static_cast<AllocationAlignment>(data - (kAlignmentPrefix - 1)); | |
1180 break; | |
1181 } | |
1182 | |
1183 STATIC_ASSERT(kNumberOfRootArrayConstants == Heap::kOldSpaceRoots); | 1172 STATIC_ASSERT(kNumberOfRootArrayConstants == Heap::kOldSpaceRoots); |
1184 STATIC_ASSERT(kNumberOfRootArrayConstants == 32); | 1173 STATIC_ASSERT(kNumberOfRootArrayConstants == 32); |
1185 SIXTEEN_CASES(kRootArrayConstantsWithSkip) | 1174 SIXTEEN_CASES(kRootArrayConstantsWithSkip) |
1186 SIXTEEN_CASES(kRootArrayConstantsWithSkip + 16) { | 1175 SIXTEEN_CASES(kRootArrayConstantsWithSkip + 16) { |
1187 int skip = source_.GetInt(); | 1176 int skip = source_.GetInt(); |
1188 current = reinterpret_cast<Object**>( | 1177 current = reinterpret_cast<Object**>( |
1189 reinterpret_cast<intptr_t>(current) + skip); | 1178 reinterpret_cast<intptr_t>(current) + skip); |
1190 // Fall through. | 1179 // Fall through. |
1191 } | 1180 } |
1192 | 1181 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 int repeats = data - kFixedRepeatStart; | 1228 int repeats = data - kFixedRepeatStart; |
1240 Object* object; | 1229 Object* object; |
1241 UnalignedCopy(&object, current - 1); | 1230 UnalignedCopy(&object, current - 1); |
1242 DCHECK(!isolate->heap()->InNewSpace(object)); | 1231 DCHECK(!isolate->heap()->InNewSpace(object)); |
1243 for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object); | 1232 for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object); |
1244 break; | 1233 break; |
1245 } | 1234 } |
1246 | 1235 |
1247 #undef SIXTEEN_CASES | 1236 #undef SIXTEEN_CASES |
1248 #undef FOUR_CASES | 1237 #undef FOUR_CASES |
1249 #undef SINGLE_CASE | |
1250 | 1238 |
1251 default: | 1239 default: |
1252 CHECK(false); | 1240 CHECK(false); |
1253 } | 1241 } |
1254 } | 1242 } |
1255 CHECK_EQ(limit, current); | 1243 CHECK_EQ(limit, current); |
1256 return true; | 1244 return true; |
1257 } | 1245 } |
1258 | 1246 |
1259 | 1247 |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1567 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject); | 1555 DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject); |
1568 sink_->Put(kAttachedReference + kPlain + kStartOfObject, "Global Proxy"); | 1556 sink_->Put(kAttachedReference + kPlain + kStartOfObject, "Global Proxy"); |
1569 sink_->PutInt(kGlobalProxyReference, "kGlobalProxyReference"); | 1557 sink_->PutInt(kGlobalProxyReference, "kGlobalProxyReference"); |
1570 } else { | 1558 } else { |
1571 if (FLAG_trace_serializer) { | 1559 if (FLAG_trace_serializer) { |
1572 PrintF(" Encoding back reference to: "); | 1560 PrintF(" Encoding back reference to: "); |
1573 obj->ShortPrint(); | 1561 obj->ShortPrint(); |
1574 PrintF("\n"); | 1562 PrintF("\n"); |
1575 } | 1563 } |
1576 | 1564 |
1577 PutAlignmentPrefix(obj); | |
1578 AllocationSpace space = back_reference.space(); | 1565 AllocationSpace space = back_reference.space(); |
1579 if (skip == 0) { | 1566 if (skip == 0) { |
1580 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRef"); | 1567 sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRef"); |
1581 } else { | 1568 } else { |
1582 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space, | 1569 sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space, |
1583 "BackRefWithSkip"); | 1570 "BackRefWithSkip"); |
1584 sink_->PutInt(skip, "BackRefSkipDistance"); | 1571 sink_->PutInt(skip, "BackRefSkipDistance"); |
1585 } | 1572 } |
1586 PutBackReference(obj, back_reference); | 1573 PutBackReference(obj, back_reference); |
1587 } | 1574 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1661 } | 1648 } |
1662 | 1649 |
1663 | 1650 |
1664 void Serializer::PutBackReference(HeapObject* object, BackReference reference) { | 1651 void Serializer::PutBackReference(HeapObject* object, BackReference reference) { |
1665 DCHECK(BackReferenceIsAlreadyAllocated(reference)); | 1652 DCHECK(BackReferenceIsAlreadyAllocated(reference)); |
1666 sink_->PutInt(reference.reference(), "BackRefValue"); | 1653 sink_->PutInt(reference.reference(), "BackRefValue"); |
1667 hot_objects_.Add(object); | 1654 hot_objects_.Add(object); |
1668 } | 1655 } |
1669 | 1656 |
1670 | 1657 |
1671 int Serializer::PutAlignmentPrefix(HeapObject* object) { | |
1672 AllocationAlignment alignment = object->RequiredAlignment(); | |
1673 if (alignment != kWordAligned) { | |
1674 DCHECK(1 <= alignment && alignment <= 3); | |
1675 byte prefix = (kAlignmentPrefix - 1) + alignment; | |
1676 sink_->Put(prefix, "Alignment"); | |
1677 return Heap::GetMaximumFillToAlign(alignment); | |
1678 } | |
1679 return 0; | |
1680 } | |
1681 | |
1682 | |
1683 void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, | 1658 void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, |
1684 WhereToPoint where_to_point, int skip) { | 1659 WhereToPoint where_to_point, int skip) { |
1685 if (obj->IsMap()) { | 1660 if (obj->IsMap()) { |
1686 // The code-caches link to context-specific code objects, which | 1661 // The code-caches link to context-specific code objects, which |
1687 // the startup and context serializes cannot currently handle. | 1662 // the startup and context serializes cannot currently handle. |
1688 DCHECK(Map::cast(obj)->code_cache() == obj->GetHeap()->empty_fixed_array()); | 1663 DCHECK(Map::cast(obj)->code_cache() == obj->GetHeap()->empty_fixed_array()); |
1689 } | 1664 } |
1690 | 1665 |
1691 // Replace typed arrays by undefined. | 1666 // Replace typed arrays by undefined. |
1692 if (obj->IsJSTypedArray()) obj = isolate_->heap()->undefined_value(); | 1667 if (obj->IsJSTypedArray()) obj = isolate_->heap()->undefined_value(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1754 sink_->Put(kNewObject + reference_representation_ + space, | 1729 sink_->Put(kNewObject + reference_representation_ + space, |
1755 "NewLargeObject"); | 1730 "NewLargeObject"); |
1756 sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords"); | 1731 sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords"); |
1757 if (object_->IsCode()) { | 1732 if (object_->IsCode()) { |
1758 sink_->Put(EXECUTABLE, "executable large object"); | 1733 sink_->Put(EXECUTABLE, "executable large object"); |
1759 } else { | 1734 } else { |
1760 sink_->Put(NOT_EXECUTABLE, "not executable large object"); | 1735 sink_->Put(NOT_EXECUTABLE, "not executable large object"); |
1761 } | 1736 } |
1762 back_reference = serializer_->AllocateLargeObject(size); | 1737 back_reference = serializer_->AllocateLargeObject(size); |
1763 } else { | 1738 } else { |
1764 int fill = serializer_->PutAlignmentPrefix(object_); | 1739 bool needs_double_align = false; |
1765 back_reference = serializer_->Allocate(space, size + fill); | 1740 // TODO(bbudge): Generalize to other alignment constraints. |
| 1741 if (object_->RequiredAlignment() == kDoubleAligned) { |
| 1742 // Add wriggle room for double alignment padding. |
| 1743 back_reference = serializer_->Allocate(space, size + kPointerSize); |
| 1744 needs_double_align = true; |
| 1745 } else { |
| 1746 back_reference = serializer_->Allocate(space, size); |
| 1747 } |
1766 sink_->Put(kNewObject + reference_representation_ + space, "NewObject"); | 1748 sink_->Put(kNewObject + reference_representation_ + space, "NewObject"); |
1767 sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords"); | 1749 if (needs_double_align) |
| 1750 sink_->PutInt(kDoubleAlignmentSentinel, "DoubleAlignSentinel"); |
| 1751 int encoded_size = size >> kObjectAlignmentBits; |
| 1752 DCHECK_NE(kDoubleAlignmentSentinel, encoded_size); |
| 1753 sink_->PutInt(encoded_size, "ObjectSizeInWords"); |
1768 } | 1754 } |
1769 | 1755 |
1770 #ifdef OBJECT_PRINT | 1756 #ifdef OBJECT_PRINT |
1771 if (FLAG_serialization_statistics) { | 1757 if (FLAG_serialization_statistics) { |
1772 serializer_->CountInstanceType(map, size); | 1758 serializer_->CountInstanceType(map, size); |
1773 } | 1759 } |
1774 #endif // OBJECT_PRINT | 1760 #endif // OBJECT_PRINT |
1775 | 1761 |
1776 // Mark this object as already serialized. | 1762 // Mark this object as already serialized. |
1777 serializer_->back_reference_map()->Add(object_, back_reference); | 1763 serializer_->back_reference_map()->Add(object_, back_reference); |
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2712 SerializedCodeData* scd = new SerializedCodeData(cached_data); | 2698 SerializedCodeData* scd = new SerializedCodeData(cached_data); |
2713 SanityCheckResult r = scd->SanityCheck(isolate, source); | 2699 SanityCheckResult r = scd->SanityCheck(isolate, source); |
2714 if (r == CHECK_SUCCESS) return scd; | 2700 if (r == CHECK_SUCCESS) return scd; |
2715 cached_data->Reject(); | 2701 cached_data->Reject(); |
2716 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); | 2702 source->GetIsolate()->counters()->code_cache_reject_reason()->AddSample(r); |
2717 delete scd; | 2703 delete scd; |
2718 return NULL; | 2704 return NULL; |
2719 } | 2705 } |
2720 } // namespace internal | 2706 } // namespace internal |
2721 } // namespace v8 | 2707 } // namespace v8 |
OLD | NEW |