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 #ifndef V8_SERIALIZE_H_ | 5 #ifndef V8_SERIALIZE_H_ |
6 #define V8_SERIALIZE_H_ | 6 #define V8_SERIALIZE_H_ |
7 | 7 |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/hashmap.h" | 9 #include "src/hashmap.h" |
10 #include "src/heap-profiler.h" | 10 #include "src/heap-profiler.h" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 | 141 |
142 // The Serializer/Deserializer class is a common superclass for Serializer and | 142 // The Serializer/Deserializer class is a common superclass for Serializer and |
143 // Deserializer which is used to store common constants and methods used by | 143 // Deserializer which is used to store common constants and methods used by |
144 // both. | 144 // both. |
145 class SerializerDeserializer: public ObjectVisitor { | 145 class SerializerDeserializer: public ObjectVisitor { |
146 public: | 146 public: |
147 static void Iterate(Isolate* isolate, ObjectVisitor* visitor); | 147 static void Iterate(Isolate* isolate, ObjectVisitor* visitor); |
148 | 148 |
149 static int nop() { return kNop; } | 149 static int nop() { return kNop; } |
150 | 150 |
| 151 // No reservation for large object space necessary. |
| 152 static const int kNumberOfPreallocatedSpaces = LO_SPACE; |
| 153 static const int kNumberOfSpaces = INVALID_SPACE; |
| 154 |
151 protected: | 155 protected: |
152 // Where the pointed-to object can be found: | 156 // Where the pointed-to object can be found: |
153 enum Where { | 157 enum Where { |
154 kNewObject = 0, // Object is next in snapshot. | 158 kNewObject = 0, // Object is next in snapshot. |
155 // 1-6 One per space. | 159 // 1-7 One per space. |
156 kRootArray = 0x9, // Object is found in root array. | 160 kRootArray = 0x9, // Object is found in root array. |
157 kPartialSnapshotCache = 0xa, // Object is in the cache. | 161 kPartialSnapshotCache = 0xa, // Object is in the cache. |
158 kExternalReference = 0xb, // Pointer to an external reference. | 162 kExternalReference = 0xb, // Pointer to an external reference. |
159 kSkip = 0xc, // Skip n bytes. | 163 kSkip = 0xc, // Skip n bytes. |
160 kBuiltin = 0xd, // Builtin code object. | 164 kBuiltin = 0xd, // Builtin code object. |
161 kAttachedReference = 0xe, // Object is described in an attached list. | 165 kAttachedReference = 0xe, // Object is described in an attached list. |
162 kNop = 0xf, // Does nothing, used to pad. | 166 kNop = 0xf, // Does nothing, used to pad. |
163 kBackref = 0x10, // Object is described relative to end. | 167 kBackref = 0x10, // Object is described relative to end. |
164 // 0x11-0x16 One per space. | 168 // 0x11-0x17 One per space. |
165 kBackrefWithSkip = 0x18, // Object is described relative to end. | 169 kBackrefWithSkip = 0x18, // Object is described relative to end. |
166 // 0x19-0x1e One per space. | 170 // 0x19-0x1f One per space. |
167 // 0x20-0x3f Used by misc. tags below. | 171 // 0x20-0x3f Used by misc. tags below. |
168 kPointedToMask = 0x3f | 172 kPointedToMask = 0x3f |
169 }; | 173 }; |
170 | 174 |
171 // How to code the pointer to the object. | 175 // How to code the pointer to the object. |
172 enum HowToCode { | 176 enum HowToCode { |
173 kPlain = 0, // Straight pointer. | 177 kPlain = 0, // Straight pointer. |
174 // What this means depends on the architecture: | 178 // What this means depends on the architecture: |
175 kFromCode = 0x40, // A pointer inlined in code. | 179 kFromCode = 0x40, // A pointer inlined in code. |
176 kHowToCodeMask = 0x40 | 180 kHowToCodeMask = 0x40 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 DCHECK(byte_code >= kConstantRepeat && byte_code <= 0x7f); | 222 DCHECK(byte_code >= kConstantRepeat && byte_code <= 0x7f); |
219 return byte_code - 0x72; | 223 return byte_code - 0x72; |
220 } | 224 } |
221 static const int kRootArrayConstants = 0xa0; | 225 static const int kRootArrayConstants = 0xa0; |
222 // 0xa0-0xbf Things from the first 32 elements of the root array. | 226 // 0xa0-0xbf Things from the first 32 elements of the root array. |
223 static const int kRootArrayNumberOfConstantEncodings = 0x20; | 227 static const int kRootArrayNumberOfConstantEncodings = 0x20; |
224 static int RootArrayConstantFromByteCode(int byte_code) { | 228 static int RootArrayConstantFromByteCode(int byte_code) { |
225 return byte_code & 0x1f; | 229 return byte_code & 0x1f; |
226 } | 230 } |
227 | 231 |
228 static const int kNumberOfSpaces = LO_SPACE; | |
229 static const int kAnyOldSpace = -1; | 232 static const int kAnyOldSpace = -1; |
230 | 233 |
231 // A bitmask for getting the space out of an instruction. | 234 // A bitmask for getting the space out of an instruction. |
232 static const int kSpaceMask = 7; | 235 static const int kSpaceMask = 7; |
| 236 STATIC_ASSERT(kNumberOfSpaces <= kSpaceMask + 1); |
233 }; | 237 }; |
234 | 238 |
235 | 239 |
236 // A Deserializer reads a snapshot and reconstructs the Object graph it defines. | 240 // A Deserializer reads a snapshot and reconstructs the Object graph it defines. |
237 class Deserializer: public SerializerDeserializer { | 241 class Deserializer: public SerializerDeserializer { |
238 public: | 242 public: |
239 // Create a deserializer from a snapshot byte source. | 243 // Create a deserializer from a snapshot byte source. |
240 explicit Deserializer(SnapshotByteSource* source); | 244 explicit Deserializer(SnapshotByteSource* source); |
241 | 245 |
242 virtual ~Deserializer(); | 246 virtual ~Deserializer(); |
243 | 247 |
244 // Deserialize the snapshot into an empty heap. | 248 // Deserialize the snapshot into an empty heap. |
245 void Deserialize(Isolate* isolate); | 249 void Deserialize(Isolate* isolate); |
246 | 250 |
247 // Deserialize a single object and the objects reachable from it. | 251 // Deserialize a single object and the objects reachable from it. |
248 void DeserializePartial(Isolate* isolate, Object** root); | 252 void DeserializePartial(Isolate* isolate, Object** root); |
249 | 253 |
250 void set_reservation(int space_number, int reservation) { | 254 void set_reservation(int space_number, int reservation) { |
251 DCHECK(space_number >= 0); | 255 DCHECK(space_number >= 0); |
252 DCHECK(space_number <= LAST_SPACE); | 256 DCHECK(space_number < kNumberOfSpaces); |
253 reservations_[space_number] = reservation; | 257 reservations_[space_number] = reservation; |
254 } | 258 } |
255 | 259 |
256 void FlushICacheForNewCodeObjects(); | 260 void FlushICacheForNewCodeObjects(); |
257 | 261 |
258 // Serialized user code reference certain objects that are provided in a list | 262 // Serialized user code reference certain objects that are provided in a list |
259 // By calling this method, we assume that we are deserializing user code. | 263 // By calling this method, we assume that we are deserializing user code. |
260 void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) { | 264 void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) { |
261 attached_objects_ = attached_objects; | 265 attached_objects_ = attached_objects; |
262 } | 266 } |
(...skipping 12 matching lines...) Expand all Loading... |
275 void RelinkAllocationSite(AllocationSite* site); | 279 void RelinkAllocationSite(AllocationSite* site); |
276 | 280 |
277 // Fills in some heap data in an area from start to end (non-inclusive). The | 281 // Fills in some heap data in an area from start to end (non-inclusive). The |
278 // space id is used for the write barrier. The object_address is the address | 282 // space id is used for the write barrier. The object_address is the address |
279 // of the object we are writing into, or NULL if we are not writing into an | 283 // of the object we are writing into, or NULL if we are not writing into an |
280 // object, i.e. if we are writing a series of tagged values that are not on | 284 // object, i.e. if we are writing a series of tagged values that are not on |
281 // the heap. | 285 // the heap. |
282 void ReadChunk( | 286 void ReadChunk( |
283 Object** start, Object** end, int space, Address object_address); | 287 Object** start, Object** end, int space, Address object_address); |
284 void ReadObject(int space_number, Object** write_back); | 288 void ReadObject(int space_number, Object** write_back); |
| 289 Address Allocate(int space_index, int size); |
285 | 290 |
286 // Special handling for serialized code like hooking up internalized strings. | 291 // Special handling for serialized code like hooking up internalized strings. |
287 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); | 292 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); |
288 Object* ProcessBackRefInSerializedCode(Object* obj); | 293 Object* ProcessBackRefInSerializedCode(Object* obj); |
289 | 294 |
290 // This routine both allocates a new object, and also keeps | |
291 // track of where objects have been allocated so that we can | |
292 // fix back references when deserializing. | |
293 Address Allocate(int space_index, int size) { | |
294 Address address = high_water_[space_index]; | |
295 high_water_[space_index] = address + size; | |
296 return address; | |
297 } | |
298 | |
299 // This returns the address of an object that has been described in the | 295 // This returns the address of an object that has been described in the |
300 // snapshot as being offset bytes back in a particular space. | 296 // snapshot as being offset bytes back in a particular space. |
301 HeapObject* GetAddressFromEnd(int space) { | 297 HeapObject* GetAddressFromEnd(int space) { |
302 int offset = source_->GetInt(); | 298 int offset = source_->GetInt(); |
| 299 if (space == LO_SPACE) return deserialized_large_objects_[offset]; |
| 300 DCHECK(space < kNumberOfPreallocatedSpaces); |
303 offset <<= kObjectAlignmentBits; | 301 offset <<= kObjectAlignmentBits; |
304 return HeapObject::FromAddress(high_water_[space] - offset); | 302 return HeapObject::FromAddress(high_water_[space] - offset); |
305 } | 303 } |
306 | 304 |
307 // Cached current isolate. | 305 // Cached current isolate. |
308 Isolate* isolate_; | 306 Isolate* isolate_; |
309 | 307 |
310 // Objects from the attached object descriptions in the serialized user code. | 308 // Objects from the attached object descriptions in the serialized user code. |
311 Vector<Handle<Object> >* attached_objects_; | 309 Vector<Handle<Object> >* attached_objects_; |
312 | 310 |
313 SnapshotByteSource* source_; | 311 SnapshotByteSource* source_; |
314 // This is the address of the next object that will be allocated in each | 312 // This is the address of the next object that will be allocated in each |
315 // space. It is used to calculate the addresses of back-references. | 313 // space. It is used to calculate the addresses of back-references. |
316 Address high_water_[LAST_SPACE + 1]; | 314 Address high_water_[kNumberOfPreallocatedSpaces]; |
317 | 315 |
318 int reservations_[LAST_SPACE + 1]; | 316 int reservations_[kNumberOfSpaces]; |
319 static const intptr_t kUninitializedReservation = -1; | 317 static const intptr_t kUninitializedReservation = -1; |
320 | 318 |
321 ExternalReferenceDecoder* external_reference_decoder_; | 319 ExternalReferenceDecoder* external_reference_decoder_; |
322 | 320 |
| 321 List<HeapObject*> deserialized_large_objects_; |
| 322 |
323 DISALLOW_COPY_AND_ASSIGN(Deserializer); | 323 DISALLOW_COPY_AND_ASSIGN(Deserializer); |
324 }; | 324 }; |
325 | 325 |
326 | 326 |
327 // Mapping objects to their location after deserialization. | 327 // Mapping objects to their location after deserialization. |
328 // This is used during building, but not at runtime by V8. | 328 // This is used during building, but not at runtime by V8. |
329 class SerializationAddressMapper { | 329 class SerializationAddressMapper { |
330 public: | 330 public: |
331 SerializationAddressMapper() | 331 SerializationAddressMapper() |
332 : no_allocation_(), | 332 : no_allocation_(), |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 HowToCode how_to_code, | 459 HowToCode how_to_code, |
460 WhereToPoint where_to_point, | 460 WhereToPoint where_to_point, |
461 int skip) = 0; | 461 int skip) = 0; |
462 void SerializeReferenceToPreviousObject(HeapObject* heap_object, | 462 void SerializeReferenceToPreviousObject(HeapObject* heap_object, |
463 HowToCode how_to_code, | 463 HowToCode how_to_code, |
464 WhereToPoint where_to_point, | 464 WhereToPoint where_to_point, |
465 int skip); | 465 int skip); |
466 void InitializeAllocators(); | 466 void InitializeAllocators(); |
467 // This will return the space for an object. | 467 // This will return the space for an object. |
468 static int SpaceOfObject(HeapObject* object); | 468 static int SpaceOfObject(HeapObject* object); |
| 469 int AllocateLargeObject(int size); |
469 int Allocate(int space, int size); | 470 int Allocate(int space, int size); |
470 int EncodeExternalReference(Address addr) { | 471 int EncodeExternalReference(Address addr) { |
471 return external_reference_encoder_->Encode(addr); | 472 return external_reference_encoder_->Encode(addr); |
472 } | 473 } |
473 | 474 |
474 int SpaceAreaSize(int space); | 475 int SpaceAreaSize(int space); |
475 | 476 |
476 // Some roots should not be serialized, because their actual value depends on | 477 // Some roots should not be serialized, because their actual value depends on |
477 // absolute addresses and they are reset after deserialization, anyway. | 478 // absolute addresses and they are reset after deserialization, anyway. |
478 bool ShouldBeSkipped(Object** current); | 479 bool ShouldBeSkipped(Object** current); |
479 | 480 |
480 Isolate* isolate_; | 481 Isolate* isolate_; |
481 // Keep track of the fullness of each space in order to generate | 482 // Keep track of the fullness of each space in order to generate |
482 // relative addresses for back references. | 483 // relative addresses for back references. |
483 int fullness_[LAST_SPACE + 1]; | 484 int fullness_[kNumberOfSpaces]; |
484 SnapshotByteSink* sink_; | 485 SnapshotByteSink* sink_; |
485 ExternalReferenceEncoder* external_reference_encoder_; | 486 ExternalReferenceEncoder* external_reference_encoder_; |
486 | 487 |
487 SerializationAddressMapper address_mapper_; | 488 SerializationAddressMapper address_mapper_; |
488 intptr_t root_index_wave_front_; | 489 intptr_t root_index_wave_front_; |
489 void Pad(); | 490 void Pad(); |
490 | 491 |
491 friend class ObjectSerializer; | 492 friend class ObjectSerializer; |
492 friend class Deserializer; | 493 friend class Deserializer; |
493 | 494 |
494 // We may not need the code address map for logging for every instance | 495 // We may not need the code address map for logging for every instance |
495 // of the serializer. Initialize it on demand. | 496 // of the serializer. Initialize it on demand. |
496 void InitializeCodeAddressMap(); | 497 void InitializeCodeAddressMap(); |
497 | 498 |
498 private: | 499 private: |
499 CodeAddressMap* code_address_map_; | 500 CodeAddressMap* code_address_map_; |
| 501 // We map serialized large objects to indexes for back-referencing. |
| 502 int seen_large_objects_index_; |
500 DISALLOW_COPY_AND_ASSIGN(Serializer); | 503 DISALLOW_COPY_AND_ASSIGN(Serializer); |
501 }; | 504 }; |
502 | 505 |
503 | 506 |
504 class PartialSerializer : public Serializer { | 507 class PartialSerializer : public Serializer { |
505 public: | 508 public: |
506 PartialSerializer(Isolate* isolate, | 509 PartialSerializer(Isolate* isolate, |
507 Serializer* startup_snapshot_serializer, | 510 Serializer* startup_snapshot_serializer, |
508 SnapshotByteSink* sink) | 511 SnapshotByteSink* sink) |
509 : Serializer(isolate, sink), | 512 : Serializer(isolate, sink), |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 // The data header consists of int-sized entries: | 687 // The data header consists of int-sized entries: |
685 // [0] version hash | 688 // [0] version hash |
686 // [1] number of code stub keys | 689 // [1] number of code stub keys |
687 // [2] payload length | 690 // [2] payload length |
688 // [3..9] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE. | 691 // [3..9] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE. |
689 static const int kCheckSumOffset = 0; | 692 static const int kCheckSumOffset = 0; |
690 static const int kNumCodeStubKeysOffset = 1; | 693 static const int kNumCodeStubKeysOffset = 1; |
691 static const int kPayloadLengthOffset = 2; | 694 static const int kPayloadLengthOffset = 2; |
692 static const int kReservationsOffset = 3; | 695 static const int kReservationsOffset = 3; |
693 | 696 |
694 static const int kNumSpaces = PROPERTY_CELL_SPACE - NEW_SPACE + 1; | 697 static const int kHeaderEntries = |
695 static const int kHeaderEntries = kReservationsOffset + kNumSpaces; | 698 kReservationsOffset + SerializerDeserializer::kNumberOfSpaces; |
696 static const int kHeaderSize = kHeaderEntries * kIntSize; | 699 static const int kHeaderSize = kHeaderEntries * kIntSize; |
697 | 700 |
698 // Following the header, we store, in sequential order | 701 // Following the header, we store, in sequential order |
699 // - code stub keys | 702 // - code stub keys |
700 // - serialization payload | 703 // - serialization payload |
701 | 704 |
702 ScriptData* script_data_; | 705 ScriptData* script_data_; |
703 bool owns_script_data_; | 706 bool owns_script_data_; |
704 }; | 707 }; |
705 } } // namespace v8::internal | 708 } } // namespace v8::internal |
706 | 709 |
707 #endif // V8_SERIALIZE_H_ | 710 #endif // V8_SERIALIZE_H_ |
OLD | NEW |