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 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 bool AtEOF() { | 389 bool AtEOF() { |
390 return position_ == length_; | 390 return position_ == length_; |
391 } | 391 } |
392 | 392 |
393 private: | 393 private: |
394 const byte* data_; | 394 const byte* data_; |
395 int length_; | 395 int length_; |
396 int position_; | 396 int position_; |
397 }; | 397 }; |
398 | 398 |
| 399 // It is very common to have a reference to the object at word 10 in space 2, |
| 400 // the object at word 5 in space 2 and the object at word 28 in space 4. This |
| 401 // only works for objects in the first page of a space |
| 402 #define COMMON_REFERENCE_PATTERNS(f) \ |
| 403 f(kNumberOfSpaces, 2, 10) \ |
| 404 f(kNumberOfSpaces + 1, 2, 5) \ |
| 405 f(kNumberOfSpaces + 2, 4, 28) \ |
| 406 f(kNumberOfSpaces + 3, 2, 21) \ |
| 407 f(kNumberOfSpaces + 4, 2, 98) \ |
| 408 f(kNumberOfSpaces + 5, 2, 67) \ |
| 409 f(kNumberOfSpaces + 6, 4, 132) |
| 410 |
| 411 #define COMMON_RAW_LENGTHS(f) \ |
| 412 f(1, 1) \ |
| 413 f(2, 2) \ |
| 414 f(3, 3) \ |
| 415 f(4, 4) \ |
| 416 f(5, 5) \ |
| 417 f(6, 6) \ |
| 418 f(7, 7) \ |
| 419 f(8, 8) \ |
| 420 f(9, 12) \ |
| 421 f(10, 16) \ |
| 422 f(11, 20) \ |
| 423 f(12, 24) \ |
| 424 f(13, 28) \ |
| 425 f(14, 32) \ |
| 426 f(15, 36) |
399 | 427 |
400 // The SerDes class is a common superclass for Serializer2 and Deserializer2 | 428 // The SerDes class is a common superclass for Serializer2 and Deserializer2 |
401 // which is used to store common constants and methods used by both. | 429 // which is used to store common constants and methods used by both. |
402 // TODO(erikcorry): This should inherit from ObjectVisitor. | 430 // TODO(erikcorry): This should inherit from ObjectVisitor. |
403 class SerDes: public GenericDeserializer { | 431 class SerDes: public GenericDeserializer { |
404 protected: | 432 protected: |
405 enum DataType { | 433 enum DataType { |
406 SMI_SERIALIZATION, | 434 RAW_DATA_SERIALIZATION = 0, // And 15 common raw lengths. |
407 RAW_DATA_SERIALIZATION, | 435 OBJECT_SERIALIZATION = 16, // One variant per space. |
408 OBJECT_SERIALIZATION, | 436 CODE_OBJECT_SERIALIZATION = 25, // One per space (only code spaces in use). |
409 CODE_OBJECT_SERIALIZATION, | 437 EXTERNAL_REFERENCE_SERIALIZATION = 34, |
410 BACKREF_SERIALIZATION, | 438 EXTERNAL_BRANCH_TARGET_SERIALIZATION = 35, |
411 CODE_BACKREF_SERIALIZATION, | 439 SYNCHRONIZE = 36, |
412 EXTERNAL_REFERENCE_SERIALIZATION, | 440 START_NEW_PAGE_SERIALIZATION = 37, |
413 EXTERNAL_BRANCH_TARGET_SERIALIZATION, | 441 // Free: 38-47. |
414 SYNCHRONIZE | 442 BACKREF_SERIALIZATION = 48, // One per space, must be 16 aligned. |
| 443 // Free: 57-63. |
| 444 REFERENCE_SERIALIZATION = 64, // One per space and common references. |
| 445 CODE_BACKREF_SERIALIZATION = 80, // One per space, must be 16 aligned. |
| 446 // Free: 89-95. |
| 447 CODE_REFERENCE_SERIALIZATION = 96 // One per space, must be 16 aligned. |
| 448 // Free: 105-255. |
415 }; | 449 }; |
416 // Our Smi encoding is much more efficient for small positive integers than it | |
417 // is for negative numbers so we add a bias before encoding and subtract it | |
418 // after encoding so that popular small negative Smis are efficiently encoded. | |
419 static const int kSmiBias = 16; | |
420 static const int kLargeData = LAST_SPACE; | 450 static const int kLargeData = LAST_SPACE; |
421 static const int kLargeCode = kLargeData + 1; | 451 static const int kLargeCode = kLargeData + 1; |
422 static const int kLargeFixedArray = kLargeCode + 1; | 452 static const int kLargeFixedArray = kLargeCode + 1; |
423 static const int kNumberOfSpaces = kLargeFixedArray + 1; | 453 static const int kNumberOfSpaces = kLargeFixedArray + 1; |
424 | 454 |
425 static inline bool SpaceIsLarge(int space) { return space >= kLargeData; } | 455 static inline bool SpaceIsLarge(int space) { return space >= kLargeData; } |
426 static inline bool SpaceIsPaged(int space) { | 456 static inline bool SpaceIsPaged(int space) { |
427 return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE; | 457 return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE; |
428 } | 458 } |
429 }; | 459 }; |
(...skipping 19 matching lines...) Expand all Loading... |
449 virtual void VisitPointers(Object** start, Object** end); | 479 virtual void VisitPointers(Object** start, Object** end); |
450 | 480 |
451 virtual void VisitExternalReferences(Address* start, Address* end) { | 481 virtual void VisitExternalReferences(Address* start, Address* end) { |
452 UNREACHABLE(); | 482 UNREACHABLE(); |
453 } | 483 } |
454 | 484 |
455 virtual void VisitRuntimeEntry(RelocInfo* rinfo) { | 485 virtual void VisitRuntimeEntry(RelocInfo* rinfo) { |
456 UNREACHABLE(); | 486 UNREACHABLE(); |
457 } | 487 } |
458 | 488 |
459 int CurrentAllocationAddress(int space) { | 489 void ReadChunk(Object** start, Object** end, int space, Address address); |
460 // The three different kinds of large objects have different tags in the | 490 HeapObject* GetAddressFromStart(int space); |
461 // snapshot so the deserializer knows which kind of object to allocate, | 491 inline HeapObject* GetAddressFromEnd(int space); |
462 // but they share a fullness_ entry. | 492 Address Allocate(int space_number, Space* space, int size); |
463 if (SpaceIsLarge(space)) space = LO_SPACE; | 493 void ReadObject(int space_number, Space* space, Object** write_back); |
464 return fullness_[space]; | |
465 } | |
466 | |
467 HeapObject* GetAddress(int space); | |
468 Address Allocate(int space, int size); | |
469 bool ReadObject(Object** write_back); | |
470 | 494 |
471 // Keep track of the pages in the paged spaces. | 495 // Keep track of the pages in the paged spaces. |
472 // (In large object space we are keeping track of individual objects | 496 // (In large object space we are keeping track of individual objects |
473 // rather than pages.) In new space we just need the address of the | 497 // rather than pages.) In new space we just need the address of the |
474 // first object and the others will flow from that. | 498 // first object and the others will flow from that. |
475 List<Address> pages_[SerDes::kNumberOfSpaces]; | 499 List<Address> pages_[SerDes::kNumberOfSpaces]; |
476 | 500 |
477 SnapshotByteSource* source_; | 501 SnapshotByteSource* source_; |
478 ExternalReferenceDecoder* external_reference_decoder_; | 502 ExternalReferenceDecoder* external_reference_decoder_; |
479 // Keep track of the fullness of each space in order to generate | 503 // Keep track of the fullness of each space in order to generate |
480 // relative addresses for back references. Large objects are | 504 // relative addresses for back references. Large objects are |
481 // just numbered sequentially since relative addresses make no | 505 // just numbered sequentially since relative addresses make no |
482 // sense in large object space. | 506 // sense in large object space. |
483 int fullness_[LAST_SPACE + 1]; | 507 int fullness_[LAST_SPACE + 1]; |
| 508 Address high_water_[LAST_SPACE + 1]; |
| 509 Address last_object_address_; |
484 | 510 |
485 DISALLOW_COPY_AND_ASSIGN(Deserializer2); | 511 DISALLOW_COPY_AND_ASSIGN(Deserializer2); |
486 }; | 512 }; |
487 | 513 |
488 | 514 |
489 class SnapshotByteSink { | 515 class SnapshotByteSink { |
490 public: | 516 public: |
491 virtual ~SnapshotByteSink() { } | 517 virtual ~SnapshotByteSink() { } |
492 virtual void Put(int byte, const char* description) = 0; | 518 virtual void Put(int byte, const char* description) = 0; |
493 void PutInt(uintptr_t integer, const char* description); | 519 void PutInt(uintptr_t integer, const char* description); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 void InitializeAllocators(); | 569 void InitializeAllocators(); |
544 // This will return the space for an object. If the object is in large | 570 // This will return the space for an object. If the object is in large |
545 // object space it may return kLargeCode or kLargeFixedArray in order | 571 // object space it may return kLargeCode or kLargeFixedArray in order |
546 // to indicate to the deserializer what kind of large object allocation | 572 // to indicate to the deserializer what kind of large object allocation |
547 // to make. | 573 // to make. |
548 static int SpaceOfObject(HeapObject* object); | 574 static int SpaceOfObject(HeapObject* object); |
549 // This just returns the space of the object. It will return LO_SPACE | 575 // This just returns the space of the object. It will return LO_SPACE |
550 // for all large objects since you can't check the type of the object | 576 // for all large objects since you can't check the type of the object |
551 // once the map has been used for the serialization address. | 577 // once the map has been used for the serialization address. |
552 static int SpaceOfAlreadySerializedObject(HeapObject* object); | 578 static int SpaceOfAlreadySerializedObject(HeapObject* object); |
553 int Allocate(int space, int size); | 579 int Allocate(int space, int size, bool* new_page_started); |
554 int CurrentAllocationAddress(int space) { | 580 int CurrentAllocationAddress(int space) { |
555 if (SpaceIsLarge(space)) space = LO_SPACE; | 581 if (SpaceIsLarge(space)) space = LO_SPACE; |
556 return fullness_[space]; | 582 return fullness_[space]; |
557 } | 583 } |
558 int EncodeExternalReference(Address addr) { | 584 int EncodeExternalReference(Address addr) { |
559 return external_reference_encoder_->Encode(addr); | 585 return external_reference_encoder_->Encode(addr); |
560 } | 586 } |
561 | 587 |
562 // Keep track of the fullness of each space in order to generate | 588 // Keep track of the fullness of each space in order to generate |
563 // relative addresses for back references. Large objects are | 589 // relative addresses for back references. Large objects are |
564 // just numbered sequentially since relative addresses make no | 590 // just numbered sequentially since relative addresses make no |
565 // sense in large object space. | 591 // sense in large object space. |
566 int fullness_[LAST_SPACE + 1]; | 592 int fullness_[LAST_SPACE + 1]; |
567 SnapshotByteSink* sink_; | 593 SnapshotByteSink* sink_; |
568 int current_root_index_; | 594 int current_root_index_; |
569 ExternalReferenceEncoder* external_reference_encoder_; | 595 ExternalReferenceEncoder* external_reference_encoder_; |
570 | 596 |
571 friend class ObjectSerializer; | 597 friend class ObjectSerializer; |
572 friend class Deserializer2; | 598 friend class Deserializer2; |
573 | 599 |
574 DISALLOW_COPY_AND_ASSIGN(Serializer2); | 600 DISALLOW_COPY_AND_ASSIGN(Serializer2); |
575 }; | 601 }; |
576 | 602 |
577 } } // namespace v8::internal | 603 } } // namespace v8::internal |
578 | 604 |
579 #endif // V8_SERIALIZE_H_ | 605 #endif // V8_SERIALIZE_H_ |
OLD | NEW |