| 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 |