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