OLD | NEW |
---|---|
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 Loading... | |
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 MapExists(); | |
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 reinterpret_cast<int>(serialization_map_->Lookup(Key(obj), | |
59 Hash(obj), | |
60 false)->value); | |
61 } | |
62 | |
63 static void Map(HeapObject* obj, int to) { | |
64 MapExists(); | |
65 ASSERT(!IsMapped(obj)); | |
66 HashMap::Entry* entry = | |
67 serialization_map_->Lookup(Key(obj), Hash(obj), true); | |
68 entry->value = Value(to); | |
69 } | |
70 | |
71 static void Zap() { | |
72 if (serialization_map_ != NULL) { | |
73 delete serialization_map_; | |
74 } | |
75 serialization_map_ = NULL; | |
76 } | |
77 | |
78 private: | |
79 static bool SerializationMatchFun(void* key1, void* key2) { | |
80 return key1 == key2; | |
81 } | |
82 | |
83 static uint32_t Hash(HeapObject* obj) { | |
84 return reinterpret_cast<uint32_t>(obj->address()); | |
85 } | |
86 | |
87 static void* Key(HeapObject* obj) { | |
88 return reinterpret_cast<void*>(obj->address()); | |
89 } | |
90 | |
91 static void* Value(int v) { | |
92 return reinterpret_cast<void*>(v); | |
93 } | |
94 | |
95 // Saying it makes it so. | |
96 static void MapExists() { | |
Kasper Lund
2009/11/25 12:52:03
EnsureMapExists?
| |
97 if (serialization_map_ == NULL) { | |
98 serialization_map_ = new HashMap(&SerializationMatchFun); | |
99 } | |
100 } | |
101 | |
102 static HashMap* serialization_map_; | |
103 }; | |
104 | |
105 | |
106 HashMap* SerializationAddressMapper::serialization_map_ = NULL; | |
107 | |
108 | |
109 | |
110 | |
47 // ----------------------------------------------------------------------------- | 111 // ----------------------------------------------------------------------------- |
48 // Coding of external references. | 112 // Coding of external references. |
49 | 113 |
50 // The encoding of an external reference. The type is in the high word. | 114 // The encoding of an external reference. The type is in the high word. |
51 // The id is in the low word. | 115 // The id is in the low word. |
52 static uint32_t EncodeExternal(TypeCode type, uint16_t id) { | 116 static uint32_t EncodeExternal(TypeCode type, uint16_t id) { |
53 return static_cast<uint32_t>(type) << 16 | id; | 117 return static_cast<uint32_t>(type) << 16 | id; |
54 } | 118 } |
55 | 119 |
56 | 120 |
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
864 // We don't support serializing installed extensions. | 928 // We don't support serializing installed extensions. |
865 for (RegisteredExtension* ext = RegisteredExtension::first_extension(); | 929 for (RegisteredExtension* ext = RegisteredExtension::first_extension(); |
866 ext != NULL; | 930 ext != NULL; |
867 ext = ext->next()) { | 931 ext = ext->next()) { |
868 CHECK_NE(v8::INSTALLED, ext->state()); | 932 CHECK_NE(v8::INSTALLED, ext->state()); |
869 } | 933 } |
870 external_reference_encoder_ = new ExternalReferenceEncoder(); | 934 external_reference_encoder_ = new ExternalReferenceEncoder(); |
871 Heap::IterateRoots(this, VISIT_ONLY_STRONG); | 935 Heap::IterateRoots(this, VISIT_ONLY_STRONG); |
872 delete external_reference_encoder_; | 936 delete external_reference_encoder_; |
873 external_reference_encoder_ = NULL; | 937 external_reference_encoder_ = NULL; |
938 SerializationAddressMapper::Zap(); | |
874 } | 939 } |
875 | 940 |
876 | 941 |
877 void Serializer::VisitPointers(Object** start, Object** end) { | 942 void Serializer::VisitPointers(Object** start, Object** end) { |
878 for (Object** current = start; current < end; current++) { | 943 for (Object** current = start; current < end; current++) { |
879 if ((*current)->IsSmi()) { | 944 if ((*current)->IsSmi()) { |
880 sink_->Put(RAW_DATA_SERIALIZATION, "RawData"); | 945 sink_->Put(RAW_DATA_SERIALIZATION, "RawData"); |
881 sink_->PutInt(kPointerSize, "length"); | 946 sink_->PutInt(kPointerSize, "length"); |
882 for (int i = 0; i < kPointerSize; i++) { | 947 for (int i = 0; i < kPointerSize; i++) { |
883 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); | 948 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); |
884 } | 949 } |
885 } else { | 950 } else { |
886 SerializeObject(*current, TAGGED_REPRESENTATION); | 951 SerializeObject(*current, TAGGED_REPRESENTATION); |
887 } | 952 } |
888 } | 953 } |
889 } | 954 } |
890 | 955 |
891 | 956 |
892 void Serializer::SerializeObject( | 957 void Serializer::SerializeObject( |
893 Object* o, | 958 Object* o, |
894 ReferenceRepresentation reference_representation) { | 959 ReferenceRepresentation reference_representation) { |
895 CHECK(o->IsHeapObject()); | 960 CHECK(o->IsHeapObject()); |
896 HeapObject* heap_object = HeapObject::cast(o); | 961 HeapObject* heap_object = HeapObject::cast(o); |
897 MapWord map_word = heap_object->map_word(); | 962 if (SerializationAddressMapper::IsMapped(heap_object)) { |
898 if (map_word.IsSerializationAddress()) { | |
899 int space = SpaceOfAlreadySerializedObject(heap_object); | 963 int space = SpaceOfAlreadySerializedObject(heap_object); |
900 int address = map_word.ToSerializationAddress(); | 964 int address = SerializationAddressMapper::MappedTo(heap_object); |
901 int offset = CurrentAllocationAddress(space) - address; | 965 int offset = CurrentAllocationAddress(space) - address; |
902 bool from_start = true; | 966 bool from_start = true; |
903 if (SpaceIsPaged(space)) { | 967 if (SpaceIsPaged(space)) { |
904 if ((CurrentAllocationAddress(space) >> Page::kPageSizeBits) == | 968 if ((CurrentAllocationAddress(space) >> Page::kPageSizeBits) == |
905 (address >> Page::kPageSizeBits)) { | 969 (address >> Page::kPageSizeBits)) { |
906 from_start = false; | 970 from_start = false; |
907 address = offset; | 971 address = offset; |
908 } | 972 } |
909 } else if (space == NEW_SPACE) { | 973 } else if (space == NEW_SPACE) { |
910 if (offset < address) { | 974 if (offset < address) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
958 int size = object_->Size(); | 1022 int size = object_->Size(); |
959 | 1023 |
960 if (reference_representation_ == TAGGED_REPRESENTATION) { | 1024 if (reference_representation_ == TAGGED_REPRESENTATION) { |
961 sink_->Put(OBJECT_SERIALIZATION + space, "ObjectSerialization"); | 1025 sink_->Put(OBJECT_SERIALIZATION + space, "ObjectSerialization"); |
962 } else { | 1026 } else { |
963 CHECK_EQ(CODE_TARGET_REPRESENTATION, reference_representation_); | 1027 CHECK_EQ(CODE_TARGET_REPRESENTATION, reference_representation_); |
964 sink_->Put(CODE_OBJECT_SERIALIZATION + space, "ObjectSerialization"); | 1028 sink_->Put(CODE_OBJECT_SERIALIZATION + space, "ObjectSerialization"); |
965 } | 1029 } |
966 sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); | 1030 sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); |
967 | 1031 |
968 // Get the map before overwriting it. | |
969 Map* map = object_->map(); | |
970 // Mark this object as already serialized. | 1032 // Mark this object as already serialized. |
971 bool start_new_page; | 1033 bool start_new_page; |
972 object_->set_map_word(MapWord::FromSerializationAddress( | 1034 SerializationAddressMapper::Map( |
973 serializer_->Allocate(space, size, &start_new_page))); | 1035 object_, |
1036 serializer_->Allocate(space, size, &start_new_page)); | |
974 if (start_new_page) { | 1037 if (start_new_page) { |
975 sink_->Put(START_NEW_PAGE_SERIALIZATION, "NewPage"); | 1038 sink_->Put(START_NEW_PAGE_SERIALIZATION, "NewPage"); |
976 sink_->PutSection(space, "NewPageSpace"); | 1039 sink_->PutSection(space, "NewPageSpace"); |
977 } | 1040 } |
978 | 1041 |
979 // Serialize the map (first word of the object). | 1042 // Serialize the map (first word of the object). |
980 serializer_->SerializeObject(map, TAGGED_REPRESENTATION); | 1043 serializer_->SerializeObject(object_->map(), TAGGED_REPRESENTATION); |
981 | 1044 |
982 // Serialize the rest of the object. | 1045 // Serialize the rest of the object. |
983 CHECK_EQ(0, bytes_processed_so_far_); | 1046 CHECK_EQ(0, bytes_processed_so_far_); |
984 bytes_processed_so_far_ = kPointerSize; | 1047 bytes_processed_so_far_ = kPointerSize; |
985 object_->IterateBody(map->instance_type(), size, this); | 1048 object_->IterateBody(object_->map()->instance_type(), size, this); |
986 OutputRawData(object_->address() + size); | 1049 OutputRawData(object_->address() + size); |
987 } | 1050 } |
988 | 1051 |
989 | 1052 |
990 void Serializer::ObjectSerializer::VisitPointers(Object** start, | 1053 void Serializer::ObjectSerializer::VisitPointers(Object** start, |
991 Object** end) { | 1054 Object** end) { |
992 Object** current = start; | 1055 Object** current = start; |
993 while (current < end) { | 1056 while (current < end) { |
994 while (current < end && (*current)->IsSmi()) current++; | 1057 while (current < end && (*current)->IsSmi()) current++; |
995 if (current < end) OutputRawData(reinterpret_cast<Address>(current)); | 1058 if (current < end) OutputRawData(reinterpret_cast<Address>(current)); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1037 serializer_->SerializeObject(target, CODE_TARGET_REPRESENTATION); | 1100 serializer_->SerializeObject(target, CODE_TARGET_REPRESENTATION); |
1038 bytes_processed_so_far_ += Assembler::kCallTargetSize; | 1101 bytes_processed_so_far_ += Assembler::kCallTargetSize; |
1039 } | 1102 } |
1040 | 1103 |
1041 | 1104 |
1042 void Serializer::ObjectSerializer::VisitExternalAsciiString( | 1105 void Serializer::ObjectSerializer::VisitExternalAsciiString( |
1043 v8::String::ExternalAsciiStringResource** resource_pointer) { | 1106 v8::String::ExternalAsciiStringResource** resource_pointer) { |
1044 Address references_start = reinterpret_cast<Address>(resource_pointer); | 1107 Address references_start = reinterpret_cast<Address>(resource_pointer); |
1045 OutputRawData(references_start); | 1108 OutputRawData(references_start); |
1046 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { | 1109 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { |
1047 // Use raw_unchecked when maps are munged. | 1110 Object* source = Heap::natives_source_cache()->get(i); |
1048 Object* source = Heap::raw_unchecked_natives_source_cache()->get(i); | |
1049 if (!source->IsUndefined()) { | 1111 if (!source->IsUndefined()) { |
1050 // Don't use cast when maps are munged. | 1112 ExternalAsciiString* string = ExternalAsciiString::cast(source); |
1051 ExternalAsciiString* string = | |
1052 reinterpret_cast<ExternalAsciiString*>(source); | |
1053 typedef v8::String::ExternalAsciiStringResource Resource; | 1113 typedef v8::String::ExternalAsciiStringResource Resource; |
1054 Resource* resource = string->resource(); | 1114 Resource* resource = string->resource(); |
1055 if (resource == *resource_pointer) { | 1115 if (resource == *resource_pointer) { |
1056 sink_->Put(NATIVES_STRING_RESOURCE, "NativesStringResource"); | 1116 sink_->Put(NATIVES_STRING_RESOURCE, "NativesStringResource"); |
1057 sink_->PutSection(i, "NativesStringResourceEnd"); | 1117 sink_->PutSection(i, "NativesStringResourceEnd"); |
1058 bytes_processed_so_far_ += sizeof(resource); | 1118 bytes_processed_so_far_ += sizeof(resource); |
1059 return; | 1119 return; |
1060 } | 1120 } |
1061 } | 1121 } |
1062 } | 1122 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1154 fullness_[space] = RoundUp(fullness_[space], Page::kPageSize); | 1214 fullness_[space] = RoundUp(fullness_[space], Page::kPageSize); |
1155 } | 1215 } |
1156 } | 1216 } |
1157 int allocation_address = fullness_[space]; | 1217 int allocation_address = fullness_[space]; |
1158 fullness_[space] = allocation_address + size; | 1218 fullness_[space] = allocation_address + size; |
1159 return allocation_address; | 1219 return allocation_address; |
1160 } | 1220 } |
1161 | 1221 |
1162 | 1222 |
1163 } } // namespace v8::internal | 1223 } } // namespace v8::internal |
OLD | NEW |