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 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
278 Add(string, BackReference::SourceReference()); | 278 Add(string, BackReference::SourceReference()); |
279 } | 279 } |
280 | 280 |
281 private: | 281 private: |
282 DisallowHeapAllocation no_allocation_; | 282 DisallowHeapAllocation no_allocation_; |
283 HashMap* map_; | 283 HashMap* map_; |
284 DISALLOW_COPY_AND_ASSIGN(BackReferenceMap); | 284 DISALLOW_COPY_AND_ASSIGN(BackReferenceMap); |
285 }; | 285 }; |
286 | 286 |
287 | 287 |
288 class HotObjectsList { | |
289 public: | |
290 HotObjectsList() : index_(0) { | |
291 for (int i = 0; i < kSize; i++) circular_queue_[i] = NULL; | |
292 } | |
293 | |
294 void Add(HeapObject* object) { | |
295 circular_queue_[index_] = object; | |
296 index_ = (index_ + 1) & kSizeMask; | |
297 } | |
298 | |
299 HeapObject* Get(int index) { | |
300 DCHECK_NE(NULL, circular_queue_[index]); | |
301 return circular_queue_[index]; | |
302 } | |
303 | |
304 static const int kNotFound = -1; | |
305 | |
306 int Find(HeapObject* object) { | |
307 for (int i = 0; i < kSize; i++) { | |
308 if (circular_queue_[i] == object) return i; | |
309 } | |
310 return kNotFound; | |
311 } | |
312 | |
313 static const int kSize = 8; | |
314 | |
315 private: | |
316 STATIC_ASSERT(IS_POWER_OF_TWO(kSize)); | |
317 static const int kSizeMask = kSize - 1; | |
318 HeapObject* circular_queue_[kSize]; | |
319 int index_; | |
320 | |
321 DISALLOW_COPY_AND_ASSIGN(HotObjectsList); | |
322 }; | |
323 | |
324 | |
288 // The Serializer/Deserializer class is a common superclass for Serializer and | 325 // The Serializer/Deserializer class is a common superclass for Serializer and |
289 // Deserializer which is used to store common constants and methods used by | 326 // Deserializer which is used to store common constants and methods used by |
290 // both. | 327 // both. |
291 class SerializerDeserializer: public ObjectVisitor { | 328 class SerializerDeserializer: public ObjectVisitor { |
292 public: | 329 public: |
293 static void Iterate(Isolate* isolate, ObjectVisitor* visitor); | 330 static void Iterate(Isolate* isolate, ObjectVisitor* visitor); |
294 | 331 |
295 static int nop() { return kNop; } | 332 static int nop() { return kNop; } |
296 | 333 |
297 // No reservation for large object space necessary. | 334 // No reservation for large object space necessary. |
298 static const int kNumberOfPreallocatedSpaces = LO_SPACE; | 335 static const int kNumberOfPreallocatedSpaces = LO_SPACE; |
299 static const int kNumberOfSpaces = LAST_SPACE + 1; | 336 static const int kNumberOfSpaces = LAST_SPACE + 1; |
300 | 337 |
301 protected: | 338 protected: |
302 // Where the pointed-to object can be found: | 339 // Where the pointed-to object can be found: |
303 enum Where { | 340 enum Where { |
304 kNewObject = 0, // Object is next in snapshot. | 341 kNewObject = 0, // Object is next in snapshot. |
305 // 1-7 One per space. | 342 // 1-7 One per space. |
343 // 0x8 Unused. | |
306 kRootArray = 0x9, // Object is found in root array. | 344 kRootArray = 0x9, // Object is found in root array. |
307 kPartialSnapshotCache = 0xa, // Object is in the cache. | 345 kPartialSnapshotCache = 0xa, // Object is in the cache. |
308 kExternalReference = 0xb, // Pointer to an external reference. | 346 kExternalReference = 0xb, // Pointer to an external reference. |
309 kSkip = 0xc, // Skip n bytes. | 347 kSkip = 0xc, // Skip n bytes. |
310 kBuiltin = 0xd, // Builtin code object. | 348 kBuiltin = 0xd, // Builtin code object. |
311 kAttachedReference = 0xe, // Object is described in an attached list. | 349 kAttachedReference = 0xe, // Object is described in an attached list. |
312 // 0xf Used by misc. See below. | 350 // 0xf Used by misc. See below. |
313 kBackref = 0x10, // Object is described relative to end. | 351 kBackref = 0x10, // Object is described relative to end. |
314 // 0x11-0x17 One per space. | 352 // 0x11-0x17 One per space. |
315 kBackrefWithSkip = 0x18, // Object is described relative to end. | 353 kBackrefWithSkip = 0x18, // Object is described relative to end. |
(...skipping 23 matching lines...) Expand all Loading... | |
339 kInnerPointer = 0x80, // First insn in code object or payload of cell. | 377 kInnerPointer = 0x80, // First insn in code object or payload of cell. |
340 kWhereToPointMask = 0x80 | 378 kWhereToPointMask = 0x80 |
341 }; | 379 }; |
342 | 380 |
343 // Misc. | 381 // Misc. |
344 // Raw data to be copied from the snapshot. This byte code does not advance | 382 // Raw data to be copied from the snapshot. This byte code does not advance |
345 // the current pointer, which is used for code objects, where we write the | 383 // the current pointer, which is used for code objects, where we write the |
346 // entire code in one memcpy, then fix up stuff with kSkip and other byte | 384 // entire code in one memcpy, then fix up stuff with kSkip and other byte |
347 // codes that overwrite data. | 385 // codes that overwrite data. |
348 static const int kRawData = 0x20; | 386 static const int kRawData = 0x20; |
349 // Some common raw lengths: 0x21-0x3f. These autoadvance the current pointer. | 387 // Some common raw lengths: 0x21-0x3f. |
388 // These autoadvance the current pointer. | |
389 static const int kOnePointerRawData = 0x21; | |
390 | |
391 static const int kVariableRepeat = 0x60; | |
392 // 0x61-0x6f Repeat last word | |
393 static const int kFixedRepeat = 0x61; | |
394 static const int kFixedRepeatBase = kFixedRepeat - 1; | |
395 static const int kLastFixedRepeat = 0x6f; | |
396 static const int kMaxFixedRepeats = kLastFixedRepeat - kFixedRepeatBase; | |
397 static int CodeForRepeats(int repeats) { | |
398 DCHECK(repeats >= 1 && repeats <= kMaxFixedRepeats); | |
399 return kFixedRepeatBase + repeats; | |
400 } | |
401 static int RepeatsForCode(int byte_code) { | |
402 DCHECK(byte_code > kFixedRepeatBase && byte_code <= kLastFixedRepeat); | |
403 return byte_code - kFixedRepeatBase; | |
404 } | |
405 | |
406 // Hot objects are a small set of recently seen or back-referenced objects. | |
407 // They are represented by a single opcode to save space. | |
408 // We use 0x70..0x77 for 8 hot objects, and 0x78..0x7f to add skip. | |
409 static const int kHotObject = 0x70; | |
410 static const int kMaxHotObjectIndex = 0x77 - kHotObject; | |
411 static const int kHotObjectWithSkip = 0x78; | |
412 STATIC_ASSERT(HotObjectsList::kSize == kMaxHotObjectIndex + 1); | |
413 STATIC_ASSERT(0x7f - kHotObjectWithSkip == kMaxHotObjectIndex); | |
414 static const int kHotObjectIndexMask = 0x7; | |
415 | |
416 static const int kRootArrayConstants = 0xa0; | |
417 // 0xa0-0xbf Things from the first 32 elements of the root array. | |
418 static const int kRootArrayNumberOfConstantEncodings = 0x20; | |
419 static int RootArrayConstantFromByteCode(int byte_code) { | |
420 return byte_code & 0x1f; | |
421 } | |
422 | |
423 // Do nothing, used for padding. | |
424 static const int kNop = 0xf; | |
425 | |
426 // Move to next reserved chunk. | |
427 static const int kNextChunk = 0x4f; | |
428 | |
350 // A tag emitted at strategic points in the snapshot to delineate sections. | 429 // A tag emitted at strategic points in the snapshot to delineate sections. |
351 // If the deserializer does not find these at the expected moments then it | 430 // If the deserializer does not find these at the expected moments then it |
352 // is an indication that the snapshot and the VM do not fit together. | 431 // is an indication that the snapshot and the VM do not fit together. |
353 // Examine the build process for architecture, version or configuration | 432 // Examine the build process for architecture, version or configuration |
354 // mismatches. | 433 // mismatches. |
355 static const int kSynchronize = 0x70; | 434 static const int kSynchronize = 0x8f; |
435 | |
356 // Used for the source code of the natives, which is in the executable, but | 436 // Used for the source code of the natives, which is in the executable, but |
357 // is referred to from external strings in the snapshot. | 437 // is referred to from external strings in the snapshot. |
358 static const int kNativesStringResource = 0x71; | 438 static const int kNativesStringResource = 0xcf; |
359 static const int kRepeat = 0x72; | |
360 static const int kConstantRepeat = 0x73; | |
361 // 0x73-0x7f Repeat last word (subtract 0x72 to get the count). | |
362 static const int kMaxRepeats = 0x7f - 0x72; | |
363 static int CodeForRepeats(int repeats) { | |
364 DCHECK(repeats >= 1 && repeats <= kMaxRepeats); | |
365 return 0x72 + repeats; | |
366 } | |
367 static int RepeatsForCode(int byte_code) { | |
368 DCHECK(byte_code >= kConstantRepeat && byte_code <= 0x7f); | |
369 return byte_code - 0x72; | |
370 } | |
371 static const int kRootArrayConstants = 0xa0; | |
372 // 0xa0-0xbf Things from the first 32 elements of the root array. | |
373 static const int kRootArrayNumberOfConstantEncodings = 0x20; | |
374 static int RootArrayConstantFromByteCode(int byte_code) { | |
375 return byte_code & 0x1f; | |
376 } | |
377 | |
378 static const int kNop = 0xf; // Do nothing, used for padding. | |
379 | |
380 static const int kNextChunk = 0x4f; // Move to next reserved chunk. | |
381 | 439 |
382 static const int kAnyOldSpace = -1; | 440 static const int kAnyOldSpace = -1; |
383 | 441 |
384 // A bitmask for getting the space out of an instruction. | 442 // A bitmask for getting the space out of an instruction. |
385 static const int kSpaceMask = 7; | 443 static const int kSpaceMask = 7; |
386 STATIC_ASSERT(kNumberOfSpaces <= kSpaceMask + 1); | 444 STATIC_ASSERT(kNumberOfSpaces <= kSpaceMask + 1); |
387 | 445 |
388 // Sentinel after a new object to indicate that double alignment is needed. | 446 // Sentinel after a new object to indicate that double alignment is needed. |
389 static const int kDoubleAlignmentSentinel = 0; | 447 static const int kDoubleAlignmentSentinel = 0; |
448 | |
449 // Used as index for the attached reference representing the source object. | |
450 static const int kSourceObjectReference = 0; | |
451 | |
452 HotObjectsList hot_objects_; | |
390 }; | 453 }; |
391 | 454 |
392 | 455 |
393 // A Deserializer reads a snapshot and reconstructs the Object graph it defines. | 456 // A Deserializer reads a snapshot and reconstructs the Object graph it defines. |
394 class Deserializer: public SerializerDeserializer { | 457 class Deserializer: public SerializerDeserializer { |
395 public: | 458 public: |
396 // Create a deserializer from a snapshot byte source. | 459 // Create a deserializer from a snapshot byte source. |
397 explicit Deserializer(SnapshotByteSource* source); | 460 explicit Deserializer(SnapshotByteSource* source); |
398 | 461 |
399 virtual ~Deserializer(); | 462 virtual ~Deserializer(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
442 // of the object we are writing into, or NULL if we are not writing into an | 505 // of the object we are writing into, or NULL if we are not writing into an |
443 // object, i.e. if we are writing a series of tagged values that are not on | 506 // object, i.e. if we are writing a series of tagged values that are not on |
444 // the heap. | 507 // the heap. |
445 void ReadData(Object** start, Object** end, int space, | 508 void ReadData(Object** start, Object** end, int space, |
446 Address object_address); | 509 Address object_address); |
447 void ReadObject(int space_number, Object** write_back); | 510 void ReadObject(int space_number, Object** write_back); |
448 Address Allocate(int space_index, int size); | 511 Address Allocate(int space_index, int size); |
449 | 512 |
450 // Special handling for serialized code like hooking up internalized strings. | 513 // Special handling for serialized code like hooking up internalized strings. |
451 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); | 514 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); |
452 Object* ProcessBackRefInSerializedCode(Object* obj); | |
453 | 515 |
454 // This returns the address of an object that has been described in the | 516 // This returns the address of an object that has been described in the |
455 // snapshot by chunk index and offset. | 517 // snapshot by chunk index and offset. |
456 HeapObject* GetBackReferencedObject(int space) { | 518 HeapObject* GetBackReferencedObject(int space); |
457 if (space == LO_SPACE) { | |
458 uint32_t index = source_->GetInt(); | |
459 return deserialized_large_objects_[index]; | |
460 } else { | |
461 BackReference back_reference(source_->GetInt()); | |
462 DCHECK(space < kNumberOfPreallocatedSpaces); | |
463 uint32_t chunk_index = back_reference.chunk_index(); | |
464 DCHECK_LE(chunk_index, current_chunk_[space]); | |
465 uint32_t chunk_offset = back_reference.chunk_offset(); | |
466 return HeapObject::FromAddress(reservations_[space][chunk_index].start + | |
467 chunk_offset); | |
468 } | |
469 } | |
470 | 519 |
471 // Cached current isolate. | 520 // Cached current isolate. |
472 Isolate* isolate_; | 521 Isolate* isolate_; |
473 | 522 |
474 // Objects from the attached object descriptions in the serialized user code. | 523 // Objects from the attached object descriptions in the serialized user code. |
475 Vector<Handle<Object> >* attached_objects_; | 524 Vector<Handle<Object> >* attached_objects_; |
476 | 525 |
477 SnapshotByteSource* source_; | 526 SnapshotByteSource* source_; |
478 // The address of the next object that will be allocated in each space. | 527 // The address of the next object that will be allocated in each space. |
479 // Each space has a number of chunks reserved by the GC, with each chunk | 528 // Each space has a number of chunks reserved by the GC, with each chunk |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
569 bool code_object_; | 618 bool code_object_; |
570 bool code_has_been_output_; | 619 bool code_has_been_output_; |
571 }; | 620 }; |
572 | 621 |
573 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code, | 622 virtual void SerializeObject(HeapObject* o, HowToCode how_to_code, |
574 WhereToPoint where_to_point, int skip) = 0; | 623 WhereToPoint where_to_point, int skip) = 0; |
575 | 624 |
576 void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where, | 625 void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where, |
577 int skip); | 626 int skip); |
578 | 627 |
579 void SerializeBackReference(BackReference back_reference, | 628 bool SerializeKnownObject(HeapObject* obj, HowToCode how_to_code, |
mvstanton
2014/12/03 08:22:41
Can you comment the return value, something like:
Yang
2014/12/03 08:45:07
Done.
| |
580 HowToCode how_to_code, | 629 WhereToPoint where_to_point, int skip); |
581 WhereToPoint where_to_point, int skip); | 630 |
631 inline void FlushSkip(int skip) { | |
632 if (skip != 0) { | |
633 sink_->Put(kSkip, "SkipFromSerializeObject"); | |
634 sink_->PutInt(skip, "SkipDistanceFromSerializeObject"); | |
635 } | |
636 } | |
637 | |
582 void InitializeAllocators(); | 638 void InitializeAllocators(); |
583 // This will return the space for an object. | 639 // This will return the space for an object. |
584 static AllocationSpace SpaceOfObject(HeapObject* object); | 640 static AllocationSpace SpaceOfObject(HeapObject* object); |
585 BackReference AllocateLargeObject(int size); | 641 BackReference AllocateLargeObject(int size); |
586 BackReference Allocate(AllocationSpace space, int size); | 642 BackReference Allocate(AllocationSpace space, int size); |
587 int EncodeExternalReference(Address addr) { | 643 int EncodeExternalReference(Address addr) { |
588 return external_reference_encoder_->Encode(addr); | 644 return external_reference_encoder_->Encode(addr); |
589 } | 645 } |
590 | 646 |
591 // GetInt reads 4 bytes at once, requiring padding at the end. | 647 // GetInt reads 4 bytes at once, requiring padding at the end. |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
709 class CodeSerializer : public Serializer { | 765 class CodeSerializer : public Serializer { |
710 public: | 766 public: |
711 static ScriptData* Serialize(Isolate* isolate, | 767 static ScriptData* Serialize(Isolate* isolate, |
712 Handle<SharedFunctionInfo> info, | 768 Handle<SharedFunctionInfo> info, |
713 Handle<String> source); | 769 Handle<String> source); |
714 | 770 |
715 MUST_USE_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize( | 771 MUST_USE_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize( |
716 Isolate* isolate, ScriptData* cached_data, Handle<String> source); | 772 Isolate* isolate, ScriptData* cached_data, Handle<String> source); |
717 | 773 |
718 static const int kSourceObjectIndex = 0; | 774 static const int kSourceObjectIndex = 0; |
775 STATIC_ASSERT(kSourceObjectReference == kSourceObjectIndex); | |
776 | |
719 static const int kCodeStubsBaseIndex = 1; | 777 static const int kCodeStubsBaseIndex = 1; |
720 | 778 |
721 String* source() const { | 779 String* source() const { |
722 DCHECK(!AllowHeapAllocation::IsAllowed()); | 780 DCHECK(!AllowHeapAllocation::IsAllowed()); |
723 return source_; | 781 return source_; |
724 } | 782 } |
725 | 783 |
726 List<uint32_t>* stub_keys() { return &stub_keys_; } | 784 List<uint32_t>* stub_keys() { return &stub_keys_; } |
727 int num_internalized_strings() const { return num_internalized_strings_; } | 785 int num_internalized_strings() const { return num_internalized_strings_; } |
728 | 786 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
868 // Following the header, we store, in sequential order | 926 // Following the header, we store, in sequential order |
869 // - code stub keys | 927 // - code stub keys |
870 // - serialization payload | 928 // - serialization payload |
871 | 929 |
872 ScriptData* script_data_; | 930 ScriptData* script_data_; |
873 bool owns_script_data_; | 931 bool owns_script_data_; |
874 }; | 932 }; |
875 } } // namespace v8::internal | 933 } } // namespace v8::internal |
876 | 934 |
877 #endif // V8_SERIALIZE_H_ | 935 #endif // V8_SERIALIZE_H_ |
OLD | NEW |