Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(920)

Side by Side Diff: src/serialize.cc

Issue 548149: Another step on the way to context snapshots. We can now refer to... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/serialize.h ('k') | src/snapshot-common.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 26 matching lines...) Expand all
37 #include "runtime.h" 37 #include "runtime.h"
38 #include "serialize.h" 38 #include "serialize.h"
39 #include "stub-cache.h" 39 #include "stub-cache.h"
40 #include "v8threads.h" 40 #include "v8threads.h"
41 #include "top.h" 41 #include "top.h"
42 #include "bootstrapper.h" 42 #include "bootstrapper.h"
43 43
44 namespace v8 { 44 namespace v8 {
45 namespace internal { 45 namespace internal {
46 46
47 // Mapping objects to their location after deserialization.
48 // This is used during building, but not at runtime by V8.
49 class SerializationAddressMapper {
50 public:
51 static bool IsMapped(HeapObject* obj) {
52 EnsureMapExists();
53 return serialization_map_->Lookup(Key(obj), Hash(obj), false) != NULL;
54 }
55
56 static int MappedTo(HeapObject* obj) {
57 ASSERT(IsMapped(obj));
58 return static_cast<int>(reinterpret_cast<intptr_t>(
59 serialization_map_->Lookup(Key(obj), Hash(obj), false)->value));
60 }
61
62 static void Map(HeapObject* obj, int to) {
63 EnsureMapExists();
64 ASSERT(!IsMapped(obj));
65 HashMap::Entry* entry =
66 serialization_map_->Lookup(Key(obj), Hash(obj), true);
67 entry->value = Value(to);
68 }
69
70 static void Zap() {
71 if (serialization_map_ != NULL) {
72 delete serialization_map_;
73 }
74 serialization_map_ = NULL;
75 }
76
77 private:
78 static bool SerializationMatchFun(void* key1, void* key2) {
79 return key1 == key2;
80 }
81
82 static uint32_t Hash(HeapObject* obj) {
83 return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address()));
84 }
85
86 static void* Key(HeapObject* obj) {
87 return reinterpret_cast<void*>(obj->address());
88 }
89
90 static void* Value(int v) {
91 return reinterpret_cast<void*>(v);
92 }
93
94 static void EnsureMapExists() {
95 if (serialization_map_ == NULL) {
96 serialization_map_ = new HashMap(&SerializationMatchFun);
97 }
98 }
99
100 static HashMap* serialization_map_;
101 };
102
103
104 HashMap* SerializationAddressMapper::serialization_map_ = NULL;
105
106
107
108 47
109 // ----------------------------------------------------------------------------- 48 // -----------------------------------------------------------------------------
110 // Coding of external references. 49 // Coding of external references.
111 50
112 // The encoding of an external reference. The type is in the high word. 51 // The encoding of an external reference. The type is in the high word.
113 // The id is in the low word. 52 // The id is in the low word.
114 static uint32_t EncodeExternal(TypeCode type, uint16_t id) { 53 static uint32_t EncodeExternal(TypeCode type, uint16_t id) {
115 return static_cast<uint32_t>(type) << 16 | id; 54 return static_cast<uint32_t>(type) << 16 | id;
116 } 55 }
117 56
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 579
641 void Deserializer::Deserialize() { 580 void Deserializer::Deserialize() {
642 // Don't GC while deserializing - just expand the heap. 581 // Don't GC while deserializing - just expand the heap.
643 AlwaysAllocateScope always_allocate; 582 AlwaysAllocateScope always_allocate;
644 // Don't use the free lists while deserializing. 583 // Don't use the free lists while deserializing.
645 LinearAllocationScope allocate_linearly; 584 LinearAllocationScope allocate_linearly;
646 // No active threads. 585 // No active threads.
647 ASSERT_EQ(NULL, ThreadState::FirstInUse()); 586 ASSERT_EQ(NULL, ThreadState::FirstInUse());
648 // No active handles. 587 // No active handles.
649 ASSERT(HandleScopeImplementer::instance()->blocks()->is_empty()); 588 ASSERT(HandleScopeImplementer::instance()->blocks()->is_empty());
589 // Make sure the entire partial snapshot cache is traversed, filling it with
590 // valid object pointers.
591 partial_snapshot_cache_length_ = kPartialSnapshotCacheCapacity;
650 ASSERT_EQ(NULL, external_reference_decoder_); 592 ASSERT_EQ(NULL, external_reference_decoder_);
651 external_reference_decoder_ = new ExternalReferenceDecoder(); 593 external_reference_decoder_ = new ExternalReferenceDecoder();
652 Heap::IterateRoots(this, VISIT_ONLY_STRONG); 594 Heap::IterateStrongRoots(this, VISIT_ONLY_STRONG);
653 ASSERT(source_->AtEOF()); 595 Heap::IterateWeakRoots(this, VISIT_ALL);
654 } 596 }
655 597
656 598
657 void Deserializer::DeserializePartial(Object** root) { 599 void Deserializer::DeserializePartial(Object** root) {
658 // Don't GC while deserializing - just expand the heap. 600 // Don't GC while deserializing - just expand the heap.
659 AlwaysAllocateScope always_allocate; 601 AlwaysAllocateScope always_allocate;
660 // Don't use the free lists while deserializing. 602 // Don't use the free lists while deserializing.
661 LinearAllocationScope allocate_linearly; 603 LinearAllocationScope allocate_linearly;
662 if (external_reference_decoder_ == NULL) { 604 if (external_reference_decoder_ == NULL) {
663 external_reference_decoder_ = new ExternalReferenceDecoder(); 605 external_reference_decoder_ = new ExternalReferenceDecoder();
664 } 606 }
665 VisitPointer(root); 607 VisitPointer(root);
666 } 608 }
667 609
668 610
669 void Deserializer::TearDown() { 611 Deserializer::~Deserializer() {
612 ASSERT(source_->AtEOF());
670 if (external_reference_decoder_ != NULL) { 613 if (external_reference_decoder_ != NULL) {
671 delete external_reference_decoder_; 614 delete external_reference_decoder_;
672 external_reference_decoder_ = NULL; 615 external_reference_decoder_ = NULL;
673 } 616 }
674 } 617 }
675 618
676 619
677 // This is called on the roots. It is the driver of the deserialization 620 // This is called on the roots. It is the driver of the deserialization
678 // process. It is also called on the body of each function. 621 // process. It is also called on the body of each function.
679 void Deserializer::VisitPointers(Object** start, Object** end) { 622 void Deserializer::VisitPointers(Object** start, Object** end) {
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 NativesExternalStringResource* resource = 827 NativesExternalStringResource* resource =
885 new NativesExternalStringResource(source_vector.start()); 828 new NativesExternalStringResource(source_vector.start());
886 *current++ = reinterpret_cast<Object*>(resource); 829 *current++ = reinterpret_cast<Object*>(resource);
887 break; 830 break;
888 } 831 }
889 case ROOT_SERIALIZATION: { 832 case ROOT_SERIALIZATION: {
890 int root_id = source_->GetInt(); 833 int root_id = source_->GetInt();
891 *current++ = Heap::roots_address()[root_id]; 834 *current++ = Heap::roots_address()[root_id];
892 break; 835 break;
893 } 836 }
837 case PARTIAL_SNAPSHOT_CACHE_ENTRY: {
838 int cache_index = source_->GetInt();
839 *current++ = partial_snapshot_cache_[cache_index];
840 break;
841 }
842 case SYNCHRONIZE: {
843 // If we get here then that indicates that you have a mismatch between
844 // the number of GC roots when serializing and deserializing.
845 UNREACHABLE();
846 }
894 default: 847 default:
895 UNREACHABLE(); 848 UNREACHABLE();
896 } 849 }
897 } 850 }
898 ASSERT_EQ(current, limit); 851 ASSERT_EQ(current, limit);
899 } 852 }
900 853
901 854
902 void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) { 855 void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) {
903 const int max_shift = ((kPointerSize * kBitsPerByte) / 7) * 7; 856 const int max_shift = ((kPointerSize * kBitsPerByte) / 7) * 7;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 sink_->PutSection(character, "TagCharacter"); 890 sink_->PutSection(character, "TagCharacter");
938 } while (character != 0); 891 } while (character != 0);
939 } 892 }
940 893
941 #endif 894 #endif
942 895
943 Serializer::Serializer(SnapshotByteSink* sink) 896 Serializer::Serializer(SnapshotByteSink* sink)
944 : sink_(sink), 897 : sink_(sink),
945 current_root_index_(0), 898 current_root_index_(0),
946 external_reference_encoder_(NULL), 899 external_reference_encoder_(NULL),
947 partial_(false),
948 large_object_total_(0) { 900 large_object_total_(0) {
949 for (int i = 0; i <= LAST_SPACE; i++) { 901 for (int i = 0; i <= LAST_SPACE; i++) {
950 fullness_[i] = 0; 902 fullness_[i] = 0;
951 } 903 }
952 } 904 }
953 905
954 906
955 void Serializer::Serialize() { 907 void StartupSerializer::SerializeStrongReferences() {
956 // No active threads. 908 // No active threads.
957 CHECK_EQ(NULL, ThreadState::FirstInUse()); 909 CHECK_EQ(NULL, ThreadState::FirstInUse());
958 // No active or weak handles. 910 // No active or weak handles.
959 CHECK(HandleScopeImplementer::instance()->blocks()->is_empty()); 911 CHECK(HandleScopeImplementer::instance()->blocks()->is_empty());
960 CHECK_EQ(0, GlobalHandles::NumberOfWeakHandles()); 912 CHECK_EQ(0, GlobalHandles::NumberOfWeakHandles());
961 CHECK_EQ(NULL, external_reference_encoder_); 913 CHECK_EQ(NULL, external_reference_encoder_);
962 // We don't support serializing installed extensions. 914 // We don't support serializing installed extensions.
963 for (RegisteredExtension* ext = RegisteredExtension::first_extension(); 915 for (RegisteredExtension* ext = RegisteredExtension::first_extension();
964 ext != NULL; 916 ext != NULL;
965 ext = ext->next()) { 917 ext = ext->next()) {
966 CHECK_NE(v8::INSTALLED, ext->state()); 918 CHECK_NE(v8::INSTALLED, ext->state());
967 } 919 }
968 external_reference_encoder_ = new ExternalReferenceEncoder(); 920 external_reference_encoder_ = new ExternalReferenceEncoder();
969 Heap::IterateRoots(this, VISIT_ONLY_STRONG); 921 Heap::IterateStrongRoots(this, VISIT_ONLY_STRONG);
970 delete external_reference_encoder_; 922 delete external_reference_encoder_;
971 external_reference_encoder_ = NULL; 923 external_reference_encoder_ = NULL;
972 SerializationAddressMapper::Zap();
973 } 924 }
974 925
975 926
976 void Serializer::SerializePartial(Object** object) { 927 void PartialSerializer::Serialize(Object** object) {
977 partial_ = true;
978 external_reference_encoder_ = new ExternalReferenceEncoder(); 928 external_reference_encoder_ = new ExternalReferenceEncoder();
979 this->VisitPointer(object); 929 this->VisitPointer(object);
930
931 // After we have done the partial serialization the partial snapshot cache
932 // will contain some references needed to decode the partial snapshot. We
933 // fill it up with undefineds so it has a predictable length so the
934 // deserialization code doesn't need to know the length.
935 for (int index = partial_snapshot_cache_length_;
936 index < kPartialSnapshotCacheCapacity;
937 index++) {
938 partial_snapshot_cache_[index] = Heap::undefined_value();
939 startup_serializer_->VisitPointer(&partial_snapshot_cache_[index]);
940 }
941 partial_snapshot_cache_length_ = kPartialSnapshotCacheCapacity;
942
980 delete external_reference_encoder_; 943 delete external_reference_encoder_;
981 external_reference_encoder_ = NULL; 944 external_reference_encoder_ = NULL;
982 SerializationAddressMapper::Zap();
983 } 945 }
984 946
985 947
986 void Serializer::VisitPointers(Object** start, Object** end) { 948 void Serializer::VisitPointers(Object** start, Object** end) {
987 for (Object** current = start; current < end; current++) { 949 for (Object** current = start; current < end; current++) {
988 if ((*current)->IsSmi()) { 950 if ((*current)->IsSmi()) {
989 sink_->Put(RAW_DATA_SERIALIZATION, "RawData"); 951 sink_->Put(RAW_DATA_SERIALIZATION, "RawData");
990 sink_->PutInt(kPointerSize, "length"); 952 sink_->PutInt(kPointerSize, "length");
991 for (int i = 0; i < kPointerSize; i++) { 953 for (int i = 0; i < kPointerSize; i++) {
992 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); 954 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte");
993 } 955 }
994 } else { 956 } else {
995 SerializeObject(*current, TAGGED_REPRESENTATION); 957 SerializeObject(*current, TAGGED_REPRESENTATION);
996 } 958 }
997 } 959 }
998 } 960 }
999 961
1000 962
1001 int Serializer::RootIndex(HeapObject* heap_object) { 963 Object* SerializerDeserializer::partial_snapshot_cache_[
964 kPartialSnapshotCacheCapacity];
965 int SerializerDeserializer::partial_snapshot_cache_length_ = 0;
966
967
968 // This ensures that the partial snapshot cache keeps things alive during GC and
969 // tracks their movement. When it is called during serialization of the startup
970 // snapshot the partial snapshot is empty, so nothing happens. When the partial
971 // (context) snapshot is created, this array is populated with the pointers that
972 // the partial snapshot will need. As that happens we emit serialized objects to
973 // the startup snapshot that correspond to the elements of this cache array. On
974 // deserialization we therefore need to visit the cache array. This fills it up
975 // with pointers to deserialized objects.
976 void SerializerDeserializer::Iterate(ObjectVisitor *visitor) {
977 visitor->VisitPointers(
978 &partial_snapshot_cache_[0],
979 &partial_snapshot_cache_[partial_snapshot_cache_length_]);
980 }
981
982
983 // When deserializing we need to set the size of the snapshot cache. This means
984 // the root iteration code (above) will iterate over array elements, writing the
985 // references to deserialized objects in them.
986 void SerializerDeserializer::SetSnapshotCacheSize(int size) {
987 partial_snapshot_cache_length_ = size;
988 }
989
990
991 int PartialSerializer::PartialSnapshotCacheIndex(HeapObject* heap_object) {
992 for (int i = 0; i < partial_snapshot_cache_length_; i++) {
993 Object* entry = partial_snapshot_cache_[i];
994 if (entry == heap_object) return i;
995 }
996 // We didn't find the object in the cache. So we add it to the cache and
997 // then visit the pointer so that it becomes part of the startup snapshot
998 // and we can refer to it from the partial snapshot.
999 int length = partial_snapshot_cache_length_;
1000 CHECK(length < kPartialSnapshotCacheCapacity);
1001 partial_snapshot_cache_[length] = heap_object;
1002 startup_serializer_->VisitPointer(&partial_snapshot_cache_[length]);
1003 // We don't recurse from the startup snapshot generator into the partial
1004 // snapshot generator.
1005 ASSERT(length == partial_snapshot_cache_length_);
1006 return partial_snapshot_cache_length_++;
1007 }
1008
1009
1010 int PartialSerializer::RootIndex(HeapObject* heap_object) {
1002 for (int i = 0; i < Heap::kRootListLength; i++) { 1011 for (int i = 0; i < Heap::kRootListLength; i++) {
1003 Object* root = Heap::roots_address()[i]; 1012 Object* root = Heap::roots_address()[i];
1004 if (root == heap_object) return i; 1013 if (root == heap_object) return i;
1005 } 1014 }
1006 return kInvalidRootIndex; 1015 return kInvalidRootIndex;
1007 } 1016 }
1008 1017
1009 1018
1010 void Serializer::SerializeObject( 1019 // Encode the location of an already deserialized object in order to write its
1020 // location into a later object. We can encode the location as an offset from
1021 // the start of the deserialized objects or as an offset backwards from the
1022 // current allocation pointer.
1023 void Serializer::SerializeReferenceToPreviousObject(
1024 int space,
1025 int address,
1026 ReferenceRepresentation reference_representation) {
1027 int offset = CurrentAllocationAddress(space) - address;
1028 bool from_start = true;
1029 if (SpaceIsPaged(space)) {
1030 // For paged space it is simple to encode back from current allocation if
1031 // the object is on the same page as the current allocation pointer.
1032 if ((CurrentAllocationAddress(space) >> kPageSizeBits) ==
1033 (address >> kPageSizeBits)) {
1034 from_start = false;
1035 address = offset;
1036 }
1037 } else if (space == NEW_SPACE) {
1038 // For new space it is always simple to encode back from current allocation.
1039 if (offset < address) {
1040 from_start = false;
1041 address = offset;
1042 }
1043 }
1044 // If we are actually dealing with real offsets (and not a numbering of
1045 // all objects) then we should shift out the bits that are always 0.
1046 if (!SpaceIsLarge(space)) address >>= kObjectAlignmentBits;
1047 // On some architectures references between code objects are encoded
1048 // specially (as relative offsets). Such references have their own
1049 // special tags to simplify the deserializer.
1050 if (reference_representation == CODE_TARGET_REPRESENTATION) {
1051 if (from_start) {
1052 sink_->Put(CODE_REFERENCE_SERIALIZATION + space, "RefCodeSer");
1053 sink_->PutInt(address, "address");
1054 } else {
1055 sink_->Put(CODE_BACKREF_SERIALIZATION + space, "BackRefCodeSer");
1056 sink_->PutInt(address, "address");
1057 }
1058 } else {
1059 // Regular absolute references.
1060 CHECK_EQ(TAGGED_REPRESENTATION, reference_representation);
1061 if (from_start) {
1062 // There are some common offsets that have their own specialized encoding.
1063 #define COMMON_REFS_CASE(tag, common_space, common_offset) \
1064 if (space == common_space && address == common_offset) { \
1065 sink_->PutSection(tag + REFERENCE_SERIALIZATION, "RefSer"); \
1066 } else /* NOLINT */
1067 COMMON_REFERENCE_PATTERNS(COMMON_REFS_CASE)
1068 #undef COMMON_REFS_CASE
1069 { /* NOLINT */
1070 sink_->Put(REFERENCE_SERIALIZATION + space, "RefSer");
1071 sink_->PutInt(address, "address");
1072 }
1073 } else {
1074 sink_->Put(BACKREF_SERIALIZATION + space, "BackRefSer");
1075 sink_->PutInt(address, "address");
1076 }
1077 }
1078 }
1079
1080
1081 void StartupSerializer::SerializeObject(
1011 Object* o, 1082 Object* o,
1012 ReferenceRepresentation reference_representation) { 1083 ReferenceRepresentation reference_representation) {
1013 CHECK(o->IsHeapObject()); 1084 CHECK(o->IsHeapObject());
1014 HeapObject* heap_object = HeapObject::cast(o); 1085 HeapObject* heap_object = HeapObject::cast(o);
1015 if (partial_) { 1086
1016 int root_index = RootIndex(heap_object); 1087 if (address_mapper_.IsMapped(heap_object)) {
1017 if (root_index != kInvalidRootIndex) { 1088 int space = SpaceOfAlreadySerializedObject(heap_object);
1018 sink_->Put(ROOT_SERIALIZATION, "RootSerialization"); 1089 int address = address_mapper_.MappedTo(heap_object);
1019 sink_->PutInt(root_index, "root_index"); 1090 SerializeReferenceToPreviousObject(space,
1020 return; 1091 address,
1021 } 1092 reference_representation);
1022 // All the symbols that the snapshot needs should be in the root table. 1093 } else {
1023 ASSERT(!heap_object->IsSymbol()); 1094 // Object has not yet been serialized. Serialize it here.
1095 ObjectSerializer object_serializer(this,
1096 heap_object,
1097 sink_,
1098 reference_representation);
1099 object_serializer.Serialize();
1024 } 1100 }
1025 if (SerializationAddressMapper::IsMapped(heap_object)) { 1101 }
1102
1103
1104 void StartupSerializer::SerializeWeakReferences() {
1105 for (int i = partial_snapshot_cache_length_;
1106 i < kPartialSnapshotCacheCapacity;
1107 i++) {
1108 sink_->Put(ROOT_SERIALIZATION, "RootSerialization");
1109 sink_->PutInt(Heap::kUndefinedValueRootIndex, "root_index");
1110 }
1111 Heap::IterateWeakRoots(this, VISIT_ALL);
1112 }
1113
1114
1115 void PartialSerializer::SerializeObject(
1116 Object* o,
1117 ReferenceRepresentation reference_representation) {
1118 CHECK(o->IsHeapObject());
1119 HeapObject* heap_object = HeapObject::cast(o);
1120
1121 int root_index;
1122 if ((root_index = RootIndex(heap_object)) != kInvalidRootIndex) {
1123 sink_->Put(ROOT_SERIALIZATION, "RootSerialization");
1124 sink_->PutInt(root_index, "root_index");
1125 return;
1126 }
1127
1128 if (ShouldBeInThePartialSnapshotCache(heap_object)) {
1129 int cache_index = PartialSnapshotCacheIndex(heap_object);
1130 sink_->Put(PARTIAL_SNAPSHOT_CACHE_ENTRY, "PartialSnapshotCache");
1131 sink_->PutInt(cache_index, "partial_snapshot_cache_index");
1132 return;
1133 }
1134
1135 // Pointers from the partial snapshot to the objects in the startup snapshot
1136 // should go through the root array or through the partial snapshot cache.
1137 // If this is not the case you may have to add something to the root array.
1138 ASSERT(!startup_serializer_->address_mapper()->IsMapped(heap_object));
1139 // All the symbols that the partial snapshot needs should be either in the
1140 // root table or in the partial snapshot cache.
1141 ASSERT(!heap_object->IsSymbol());
1142
1143 if (address_mapper_.IsMapped(heap_object)) {
1026 int space = SpaceOfAlreadySerializedObject(heap_object); 1144 int space = SpaceOfAlreadySerializedObject(heap_object);
1027 int address = SerializationAddressMapper::MappedTo(heap_object); 1145 int address = address_mapper_.MappedTo(heap_object);
1028 int offset = CurrentAllocationAddress(space) - address; 1146 SerializeReferenceToPreviousObject(space,
1029 bool from_start = true; 1147 address,
1030 if (SpaceIsPaged(space)) { 1148 reference_representation);
1031 if ((CurrentAllocationAddress(space) >> kPageSizeBits) ==
1032 (address >> kPageSizeBits)) {
1033 from_start = false;
1034 address = offset;
1035 }
1036 } else if (space == NEW_SPACE) {
1037 if (offset < address) {
1038 from_start = false;
1039 address = offset;
1040 }
1041 }
1042 // If we are actually dealing with real offsets (and not a numbering of
1043 // all objects) then we should shift out the bits that are always 0.
1044 if (!SpaceIsLarge(space)) address >>= kObjectAlignmentBits;
1045 if (reference_representation == CODE_TARGET_REPRESENTATION) {
1046 if (from_start) {
1047 sink_->Put(CODE_REFERENCE_SERIALIZATION + space, "RefCodeSer");
1048 sink_->PutInt(address, "address");
1049 } else {
1050 sink_->Put(CODE_BACKREF_SERIALIZATION + space, "BackRefCodeSer");
1051 sink_->PutInt(address, "address");
1052 }
1053 } else {
1054 CHECK_EQ(TAGGED_REPRESENTATION, reference_representation);
1055 if (from_start) {
1056 #define COMMON_REFS_CASE(tag, common_space, common_offset) \
1057 if (space == common_space && address == common_offset) { \
1058 sink_->PutSection(tag + REFERENCE_SERIALIZATION, "RefSer"); \
1059 } else /* NOLINT */
1060 COMMON_REFERENCE_PATTERNS(COMMON_REFS_CASE)
1061 #undef COMMON_REFS_CASE
1062 { /* NOLINT */
1063 sink_->Put(REFERENCE_SERIALIZATION + space, "RefSer");
1064 sink_->PutInt(address, "address");
1065 }
1066 } else {
1067 sink_->Put(BACKREF_SERIALIZATION + space, "BackRefSer");
1068 sink_->PutInt(address, "address");
1069 }
1070 }
1071 } else { 1149 } else {
1072 // Object has not yet been serialized. Serialize it here. 1150 // Object has not yet been serialized. Serialize it here.
1073 ObjectSerializer serializer(this, 1151 ObjectSerializer serializer(this,
1074 heap_object, 1152 heap_object,
1075 sink_, 1153 sink_,
1076 reference_representation); 1154 reference_representation);
1077 serializer.Serialize(); 1155 serializer.Serialize();
1078 } 1156 }
1079 } 1157 }
1080 1158
1081 1159
1082
1083 void Serializer::ObjectSerializer::Serialize() { 1160 void Serializer::ObjectSerializer::Serialize() {
1084 int space = Serializer::SpaceOfObject(object_); 1161 int space = Serializer::SpaceOfObject(object_);
1085 int size = object_->Size(); 1162 int size = object_->Size();
1086 1163
1087 if (reference_representation_ == TAGGED_REPRESENTATION) { 1164 if (reference_representation_ == TAGGED_REPRESENTATION) {
1088 sink_->Put(OBJECT_SERIALIZATION + space, "ObjectSerialization"); 1165 sink_->Put(OBJECT_SERIALIZATION + space, "ObjectSerialization");
1089 } else { 1166 } else {
1090 CHECK_EQ(CODE_TARGET_REPRESENTATION, reference_representation_); 1167 CHECK_EQ(CODE_TARGET_REPRESENTATION, reference_representation_);
1091 sink_->Put(CODE_OBJECT_SERIALIZATION + space, "ObjectSerialization"); 1168 sink_->Put(CODE_OBJECT_SERIALIZATION + space, "ObjectSerialization");
1092 } 1169 }
1093 sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); 1170 sink_->PutInt(size >> kObjectAlignmentBits, "Size in words");
1094 1171
1095 LOG(SnapshotPositionEvent(object_->address(), sink_->Position())); 1172 LOG(SnapshotPositionEvent(object_->address(), sink_->Position()));
1096 1173
1097 // Mark this object as already serialized. 1174 // Mark this object as already serialized.
1098 bool start_new_page; 1175 bool start_new_page;
1099 SerializationAddressMapper::Map( 1176 int offset = serializer_->Allocate(space, size, &start_new_page);
1100 object_, 1177 serializer_->address_mapper()->AddMapping(object_, offset);
1101 serializer_->Allocate(space, size, &start_new_page));
1102 if (start_new_page) { 1178 if (start_new_page) {
1103 sink_->Put(START_NEW_PAGE_SERIALIZATION, "NewPage"); 1179 sink_->Put(START_NEW_PAGE_SERIALIZATION, "NewPage");
1104 sink_->PutSection(space, "NewPageSpace"); 1180 sink_->PutSection(space, "NewPageSpace");
1105 } 1181 }
1106 1182
1107 // Serialize the map (first word of the object). 1183 // Serialize the map (first word of the object).
1108 serializer_->SerializeObject(object_->map(), TAGGED_REPRESENTATION); 1184 serializer_->SerializeObject(object_->map(), TAGGED_REPRESENTATION);
1109 1185
1110 // Serialize the rest of the object. 1186 // Serialize the rest of the object.
1111 CHECK_EQ(0, bytes_processed_so_far_); 1187 CHECK_EQ(0, bytes_processed_so_far_);
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 fullness_[space] = RoundUp(fullness_[space], Page::kPageSize); 1356 fullness_[space] = RoundUp(fullness_[space], Page::kPageSize);
1281 } 1357 }
1282 } 1358 }
1283 int allocation_address = fullness_[space]; 1359 int allocation_address = fullness_[space];
1284 fullness_[space] = allocation_address + size; 1360 fullness_[space] = allocation_address + size;
1285 return allocation_address; 1361 return allocation_address;
1286 } 1362 }
1287 1363
1288 1364
1289 } } // namespace v8::internal 1365 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/serialize.h ('k') | src/snapshot-common.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698