OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 19 matching lines...) Expand all Loading... |
30 #include "accessors.h" | 30 #include "accessors.h" |
31 #include "api.h" | 31 #include "api.h" |
32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
33 #include "execution.h" | 33 #include "execution.h" |
34 #include "global-handles.h" | 34 #include "global-handles.h" |
35 #include "ic-inl.h" | 35 #include "ic-inl.h" |
36 #include "natives.h" | 36 #include "natives.h" |
37 #include "platform.h" | 37 #include "platform.h" |
38 #include "runtime.h" | 38 #include "runtime.h" |
39 #include "serialize.h" | 39 #include "serialize.h" |
| 40 #include "snapshot.h" |
40 #include "stub-cache.h" | 41 #include "stub-cache.h" |
41 #include "v8threads.h" | 42 #include "v8threads.h" |
42 | 43 |
43 namespace v8 { | 44 namespace v8 { |
44 namespace internal { | 45 namespace internal { |
45 | 46 |
46 | 47 |
47 // ----------------------------------------------------------------------------- | 48 // ----------------------------------------------------------------------------- |
48 // Coding of external references. | 49 // Coding of external references. |
49 | 50 |
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 isolate_ = Isolate::Current(); | 668 isolate_ = Isolate::Current(); |
668 ASSERT(isolate_ != NULL); | 669 ASSERT(isolate_ != NULL); |
669 // Don't GC while deserializing - just expand the heap. | 670 // Don't GC while deserializing - just expand the heap. |
670 AlwaysAllocateScope always_allocate; | 671 AlwaysAllocateScope always_allocate; |
671 // Don't use the free lists while deserializing. | 672 // Don't use the free lists while deserializing. |
672 LinearAllocationScope allocate_linearly; | 673 LinearAllocationScope allocate_linearly; |
673 // No active threads. | 674 // No active threads. |
674 ASSERT_EQ(NULL, isolate_->thread_manager()->FirstThreadStateInUse()); | 675 ASSERT_EQ(NULL, isolate_->thread_manager()->FirstThreadStateInUse()); |
675 // No active handles. | 676 // No active handles. |
676 ASSERT(isolate_->handle_scope_implementer()->blocks()->is_empty()); | 677 ASSERT(isolate_->handle_scope_implementer()->blocks()->is_empty()); |
677 // Make sure the entire partial snapshot cache is traversed, filling it with | |
678 // valid object pointers. | |
679 isolate_->set_serialize_partial_snapshot_cache_length( | |
680 Isolate::kPartialSnapshotCacheCapacity); | |
681 ASSERT_EQ(NULL, external_reference_decoder_); | 678 ASSERT_EQ(NULL, external_reference_decoder_); |
682 external_reference_decoder_ = new ExternalReferenceDecoder(); | 679 external_reference_decoder_ = new ExternalReferenceDecoder(); |
683 isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); | 680 isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); |
684 isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); | 681 isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); |
685 | 682 |
686 isolate_->heap()->set_global_contexts_list( | 683 isolate_->heap()->set_global_contexts_list( |
687 isolate_->heap()->undefined_value()); | 684 isolate_->heap()->undefined_value()); |
688 | 685 |
689 // Update data pointers to the external strings containing natives sources. | 686 // Update data pointers to the external strings containing natives sources. |
690 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { | 687 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) { |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 CHECK_EQ(0, isolate->global_handles()->NumberOfWeakHandles()); | 1139 CHECK_EQ(0, isolate->global_handles()->NumberOfWeakHandles()); |
1143 // We don't support serializing installed extensions. | 1140 // We don't support serializing installed extensions. |
1144 CHECK(!isolate->has_installed_extensions()); | 1141 CHECK(!isolate->has_installed_extensions()); |
1145 | 1142 |
1146 HEAP->IterateStrongRoots(this, VISIT_ONLY_STRONG); | 1143 HEAP->IterateStrongRoots(this, VISIT_ONLY_STRONG); |
1147 } | 1144 } |
1148 | 1145 |
1149 | 1146 |
1150 void PartialSerializer::Serialize(Object** object) { | 1147 void PartialSerializer::Serialize(Object** object) { |
1151 this->VisitPointer(object); | 1148 this->VisitPointer(object); |
1152 Isolate* isolate = Isolate::Current(); | |
1153 | |
1154 // After we have done the partial serialization the partial snapshot cache | |
1155 // will contain some references needed to decode the partial snapshot. We | |
1156 // fill it up with undefineds so it has a predictable length so the | |
1157 // deserialization code doesn't need to know the length. | |
1158 for (int index = isolate->serialize_partial_snapshot_cache_length(); | |
1159 index < Isolate::kPartialSnapshotCacheCapacity; | |
1160 index++) { | |
1161 isolate->serialize_partial_snapshot_cache()[index] = | |
1162 isolate->heap()->undefined_value(); | |
1163 startup_serializer_->VisitPointer( | |
1164 &isolate->serialize_partial_snapshot_cache()[index]); | |
1165 } | |
1166 isolate->set_serialize_partial_snapshot_cache_length( | |
1167 Isolate::kPartialSnapshotCacheCapacity); | |
1168 } | 1149 } |
1169 | 1150 |
1170 | 1151 |
1171 void Serializer::VisitPointers(Object** start, Object** end) { | 1152 void Serializer::VisitPointers(Object** start, Object** end) { |
1172 Isolate* isolate = Isolate::Current(); | 1153 Isolate* isolate = Isolate::Current(); |
1173 | 1154 |
1174 for (Object** current = start; current < end; current++) { | 1155 for (Object** current = start; current < end; current++) { |
1175 if (start == isolate->heap()->roots_array_start()) { | 1156 if (start == isolate->heap()->roots_array_start()) { |
1176 root_index_wave_front_ = | 1157 root_index_wave_front_ = |
1177 Max(root_index_wave_front_, static_cast<intptr_t>(current - start)); | 1158 Max(root_index_wave_front_, static_cast<intptr_t>(current - start)); |
1178 } | 1159 } |
1179 if (reinterpret_cast<Address>(current) == | 1160 if (reinterpret_cast<Address>(current) == |
1180 isolate->heap()->store_buffer()->TopAddress()) { | 1161 isolate->heap()->store_buffer()->TopAddress()) { |
1181 sink_->Put(kSkip, "Skip"); | 1162 sink_->Put(kSkip, "Skip"); |
1182 } else if ((*current)->IsSmi()) { | 1163 } else if ((*current)->IsSmi()) { |
1183 sink_->Put(kRawData, "RawData"); | 1164 sink_->Put(kRawData, "RawData"); |
1184 sink_->PutInt(kPointerSize, "length"); | 1165 sink_->PutInt(kPointerSize, "length"); |
1185 for (int i = 0; i < kPointerSize; i++) { | 1166 for (int i = 0; i < kPointerSize; i++) { |
1186 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); | 1167 sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); |
1187 } | 1168 } |
1188 } else { | 1169 } else { |
1189 SerializeObject(*current, kPlain, kStartOfObject); | 1170 SerializeObject(*current, kPlain, kStartOfObject); |
1190 } | 1171 } |
1191 } | 1172 } |
1192 } | 1173 } |
1193 | 1174 |
1194 | 1175 |
1195 // This ensures that the partial snapshot cache keeps things alive during GC and | 1176 // This ensures that the partial snapshot cache keeps things alive during GC and |
1196 // tracks their movement. When it is called during serialization of the startup | 1177 // tracks their movement. When it is called during serialization of the startup |
1197 // snapshot the partial snapshot is empty, so nothing happens. When the partial | 1178 // snapshot nothing happens. When the partial (context) snapshot is created, |
1198 // (context) snapshot is created, this array is populated with the pointers that | 1179 // this array is populated with the pointers that the partial snapshot will |
1199 // the partial snapshot will need. As that happens we emit serialized objects to | 1180 // need. As that happens we emit serialized objects to the startup snapshot |
1200 // the startup snapshot that correspond to the elements of this cache array. On | 1181 // that correspond to the elements of this cache array. On deserialization we |
1201 // deserialization we therefore need to visit the cache array. This fills it up | 1182 // therefore need to visit the cache array. This fills it up with pointers to |
1202 // with pointers to deserialized objects. | 1183 // deserialized objects. |
1203 void SerializerDeserializer::Iterate(ObjectVisitor* visitor) { | 1184 void SerializerDeserializer::Iterate(ObjectVisitor* visitor) { |
| 1185 if (Serializer::enabled()) return; |
1204 Isolate* isolate = Isolate::Current(); | 1186 Isolate* isolate = Isolate::Current(); |
1205 visitor->VisitPointers( | 1187 for (int i = 0; ; i++) { |
1206 isolate->serialize_partial_snapshot_cache(), | 1188 if (isolate->serialize_partial_snapshot_cache_length() <= i) { |
1207 &isolate->serialize_partial_snapshot_cache()[ | 1189 // Extend the array ready to get a value from the visitor when |
1208 isolate->serialize_partial_snapshot_cache_length()]); | 1190 // deserializing. |
1209 } | 1191 isolate->PushToPartialSnapshotCache(Smi::FromInt(0)); |
1210 | 1192 } |
1211 | 1193 Object** cache = isolate->serialize_partial_snapshot_cache(); |
1212 // When deserializing we need to set the size of the snapshot cache. This means | 1194 visitor->VisitPointers(&cache[i], &cache[i + 1]); |
1213 // the root iteration code (above) will iterate over array elements, writing the | 1195 // Sentinel is the undefined object, which is a root so it will not normally |
1214 // references to deserialized objects in them. | 1196 // be found in the cache. |
1215 void SerializerDeserializer::SetSnapshotCacheSize(int size) { | 1197 if (cache[i] == isolate->heap()->undefined_value()) { |
1216 Isolate::Current()->set_serialize_partial_snapshot_cache_length(size); | 1198 break; |
| 1199 } |
| 1200 } |
1217 } | 1201 } |
1218 | 1202 |
1219 | 1203 |
1220 int PartialSerializer::PartialSnapshotCacheIndex(HeapObject* heap_object) { | 1204 int PartialSerializer::PartialSnapshotCacheIndex(HeapObject* heap_object) { |
1221 Isolate* isolate = Isolate::Current(); | 1205 Isolate* isolate = Isolate::Current(); |
1222 | 1206 |
1223 for (int i = 0; | 1207 for (int i = 0; |
1224 i < isolate->serialize_partial_snapshot_cache_length(); | 1208 i < isolate->serialize_partial_snapshot_cache_length(); |
1225 i++) { | 1209 i++) { |
1226 Object* entry = isolate->serialize_partial_snapshot_cache()[i]; | 1210 Object* entry = isolate->serialize_partial_snapshot_cache()[i]; |
1227 if (entry == heap_object) return i; | 1211 if (entry == heap_object) return i; |
1228 } | 1212 } |
1229 | 1213 |
1230 // We didn't find the object in the cache. So we add it to the cache and | 1214 // We didn't find the object in the cache. So we add it to the cache and |
1231 // then visit the pointer so that it becomes part of the startup snapshot | 1215 // then visit the pointer so that it becomes part of the startup snapshot |
1232 // and we can refer to it from the partial snapshot. | 1216 // and we can refer to it from the partial snapshot. |
1233 int length = isolate->serialize_partial_snapshot_cache_length(); | 1217 int length = isolate->serialize_partial_snapshot_cache_length(); |
1234 CHECK(length < Isolate::kPartialSnapshotCacheCapacity); | 1218 isolate->PushToPartialSnapshotCache(heap_object); |
1235 isolate->serialize_partial_snapshot_cache()[length] = heap_object; | 1219 startup_serializer_->VisitPointer(reinterpret_cast<Object**>(&heap_object)); |
1236 startup_serializer_->VisitPointer( | |
1237 &isolate->serialize_partial_snapshot_cache()[length]); | |
1238 // We don't recurse from the startup snapshot generator into the partial | 1220 // We don't recurse from the startup snapshot generator into the partial |
1239 // snapshot generator. | 1221 // snapshot generator. |
1240 ASSERT(length == isolate->serialize_partial_snapshot_cache_length()); | 1222 ASSERT(length == isolate->serialize_partial_snapshot_cache_length() - 1); |
1241 isolate->set_serialize_partial_snapshot_cache_length(length + 1); | |
1242 return length; | 1223 return length; |
1243 } | 1224 } |
1244 | 1225 |
1245 | 1226 |
1246 int Serializer::RootIndex(HeapObject* heap_object, HowToCode from) { | 1227 int Serializer::RootIndex(HeapObject* heap_object, HowToCode from) { |
1247 Heap* heap = HEAP; | 1228 Heap* heap = HEAP; |
1248 if (heap->InNewSpace(heap_object)) return kInvalidRootIndex; | 1229 if (heap->InNewSpace(heap_object)) return kInvalidRootIndex; |
1249 for (int i = 0; i < root_index_wave_front_; i++) { | 1230 for (int i = 0; i < root_index_wave_front_; i++) { |
1250 Object* root = heap->roots_array_start()[i]; | 1231 Object* root = heap->roots_array_start()[i]; |
1251 if (!root->IsSmi() && root == heap_object) { | 1232 if (!root->IsSmi() && root == heap_object) { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1330 heap_object, | 1311 heap_object, |
1331 sink_, | 1312 sink_, |
1332 how_to_code, | 1313 how_to_code, |
1333 where_to_point); | 1314 where_to_point); |
1334 object_serializer.Serialize(); | 1315 object_serializer.Serialize(); |
1335 } | 1316 } |
1336 } | 1317 } |
1337 | 1318 |
1338 | 1319 |
1339 void StartupSerializer::SerializeWeakReferences() { | 1320 void StartupSerializer::SerializeWeakReferences() { |
1340 for (int i = Isolate::Current()->serialize_partial_snapshot_cache_length(); | 1321 // This phase comes right after the partial serialization (of the snapshot). |
1341 i < Isolate::kPartialSnapshotCacheCapacity; | 1322 // After we have done the partial serialization the partial snapshot cache |
1342 i++) { | 1323 // will contain some references needed to decode the partial snapshot. We |
1343 sink_->Put(kRootArray + kPlain + kStartOfObject, "RootSerialization"); | 1324 // add one entry with 'undefined' which is the sentinel that the deserializer |
1344 sink_->PutInt(Heap::kUndefinedValueRootIndex, "root_index"); | 1325 // uses to know it is done deserializing the array. |
1345 } | 1326 Isolate* isolate = Isolate::Current(); |
| 1327 Object* undefined = isolate->heap()->undefined_value(); |
| 1328 VisitPointer(&undefined); |
1346 HEAP->IterateWeakRoots(this, VISIT_ALL); | 1329 HEAP->IterateWeakRoots(this, VISIT_ALL); |
1347 } | 1330 } |
1348 | 1331 |
1349 | 1332 |
1350 void Serializer::PutRoot(int root_index, | 1333 void Serializer::PutRoot(int root_index, |
1351 HeapObject* object, | 1334 HeapObject* object, |
1352 SerializerDeserializer::HowToCode how_to_code, | 1335 SerializerDeserializer::HowToCode how_to_code, |
1353 SerializerDeserializer::WhereToPoint where_to_point) { | 1336 SerializerDeserializer::WhereToPoint where_to_point) { |
1354 if (how_to_code == kPlain && | 1337 if (how_to_code == kPlain && |
1355 where_to_point == kStartOfObject && | 1338 where_to_point == kStartOfObject && |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1699 int Serializer::SpaceAreaSize(int space) { | 1682 int Serializer::SpaceAreaSize(int space) { |
1700 if (space == CODE_SPACE) { | 1683 if (space == CODE_SPACE) { |
1701 return isolate_->memory_allocator()->CodePageAreaSize(); | 1684 return isolate_->memory_allocator()->CodePageAreaSize(); |
1702 } else { | 1685 } else { |
1703 return Page::kPageSize - Page::kObjectStartOffset; | 1686 return Page::kPageSize - Page::kObjectStartOffset; |
1704 } | 1687 } |
1705 } | 1688 } |
1706 | 1689 |
1707 | 1690 |
1708 } } // namespace v8::internal | 1691 } } // namespace v8::internal |
OLD | NEW |