| OLD | NEW | 
|---|
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 180 | 180 | 
| 181   int position() { return position_; } | 181   int position() { return position_; } | 
| 182 | 182 | 
| 183  private: | 183  private: | 
| 184   const byte* data_; | 184   const byte* data_; | 
| 185   int length_; | 185   int length_; | 
| 186   int position_; | 186   int position_; | 
| 187 }; | 187 }; | 
| 188 | 188 | 
| 189 | 189 | 
| 190 // It is very common to have a reference to objects at certain offsets in the |  | 
| 191 // heap.  These offsets have been determined experimentally.  We code |  | 
| 192 // references to such objects in a single byte that encodes the way the pointer |  | 
| 193 // is written (only plain pointers allowed), the space number and the offset. |  | 
| 194 // This only works for objects in the first page of a space.  Don't use this for |  | 
| 195 // things in newspace since it bypasses the write barrier. |  | 
| 196 |  | 
| 197 static const int k64 = (sizeof(uintptr_t) - 4) / 4; |  | 
| 198 |  | 
| 199 #define COMMON_REFERENCE_PATTERNS(f)                               \ |  | 
| 200   f(kNumberOfSpaces, 2, (11 - k64))                                \ |  | 
| 201   f((kNumberOfSpaces + 1), 2, 0)                                   \ |  | 
| 202   f((kNumberOfSpaces + 2), 2, (142 - 16 * k64))                    \ |  | 
| 203   f((kNumberOfSpaces + 3), 2, (74 - 15 * k64))                     \ |  | 
| 204   f((kNumberOfSpaces + 4), 2, 5)                                   \ |  | 
| 205   f((kNumberOfSpaces + 5), 1, 135)                                 \ |  | 
| 206   f((kNumberOfSpaces + 6), 2, (228 - 39 * k64)) |  | 
| 207 |  | 
| 208 #define COMMON_RAW_LENGTHS(f)        \ | 190 #define COMMON_RAW_LENGTHS(f)        \ | 
| 209   f(1, 1)  \ | 191   f(1, 1)  \ | 
| 210   f(2, 2)  \ | 192   f(2, 2)  \ | 
| 211   f(3, 3)  \ | 193   f(3, 3)  \ | 
| 212   f(4, 4)  \ | 194   f(4, 4)  \ | 
| 213   f(5, 5)  \ | 195   f(5, 5)  \ | 
| 214   f(6, 6)  \ | 196   f(6, 6)  \ | 
| 215   f(7, 7)  \ | 197   f(7, 7)  \ | 
| 216   f(8, 8)  \ | 198   f(8, 8)  \ | 
| 217   f(9, 12)  \ | 199   f(9, 12)  \ | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 235   enum Where { | 217   enum Where { | 
| 236     kNewObject = 0,                 // Object is next in snapshot. | 218     kNewObject = 0,                 // Object is next in snapshot. | 
| 237     // 1-8                             One per space. | 219     // 1-8                             One per space. | 
| 238     kRootArray = 0x9,               // Object is found in root array. | 220     kRootArray = 0x9,               // Object is found in root array. | 
| 239     kPartialSnapshotCache = 0xa,    // Object is in the cache. | 221     kPartialSnapshotCache = 0xa,    // Object is in the cache. | 
| 240     kExternalReference = 0xb,       // Pointer to an external reference. | 222     kExternalReference = 0xb,       // Pointer to an external reference. | 
| 241     kSkip = 0xc,                    // Skip a pointer sized cell. | 223     kSkip = 0xc,                    // Skip a pointer sized cell. | 
| 242     // 0xd-0xf                         Free. | 224     // 0xd-0xf                         Free. | 
| 243     kBackref = 0x10,                 // Object is described relative to end. | 225     kBackref = 0x10,                 // Object is described relative to end. | 
| 244     // 0x11-0x18                       One per space. | 226     // 0x11-0x18                       One per space. | 
| 245     // 0x19-0x1f                       Common backref offsets. | 227     // 0x19-0x1f                       Free. | 
| 246     kFromStart = 0x20,              // Object is described relative to start. | 228     kFromStart = 0x20,              // Object is described relative to start. | 
| 247     // 0x21-0x28                       One per space. | 229     // 0x21-0x28                       One per space. | 
| 248     // 0x29-0x2f                       Free. | 230     // 0x29-0x2f                       Free. | 
| 249     // 0x30-0x3f                       Used by misc tags below. | 231     // 0x30-0x3f                       Used by misc tags below. | 
| 250     kPointedToMask = 0x3f | 232     kPointedToMask = 0x3f | 
| 251   }; | 233   }; | 
| 252 | 234 | 
| 253   // How to code the pointer to the object. | 235   // How to code the pointer to the object. | 
| 254   enum HowToCode { | 236   enum HowToCode { | 
| 255     kPlain = 0,                          // Straight pointer. | 237     kPlain = 0,                          // Straight pointer. | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 272   // A tag emitted at strategic points in the snapshot to delineate sections. | 254   // A tag emitted at strategic points in the snapshot to delineate sections. | 
| 273   // If the deserializer does not find these at the expected moments then it | 255   // If the deserializer does not find these at the expected moments then it | 
| 274   // is an indication that the snapshot and the VM do not fit together. | 256   // is an indication that the snapshot and the VM do not fit together. | 
| 275   // Examine the build process for architecture, version or configuration | 257   // Examine the build process for architecture, version or configuration | 
| 276   // mismatches. | 258   // mismatches. | 
| 277   static const int kSynchronize = 0x70; | 259   static const int kSynchronize = 0x70; | 
| 278   // Used for the source code of the natives, which is in the executable, but | 260   // Used for the source code of the natives, which is in the executable, but | 
| 279   // is referred to from external strings in the snapshot. | 261   // is referred to from external strings in the snapshot. | 
| 280   static const int kNativesStringResource = 0x71; | 262   static const int kNativesStringResource = 0x71; | 
| 281   static const int kNewPage = 0x72; | 263   static const int kNewPage = 0x72; | 
| 282   // 0x73-0x7f                            Free. | 264   static const int kRepeat = 0x73; | 
| 283   // 0xb0-0xbf                            Free. | 265   static const int kConstantRepeat = 0x74; | 
| 284   // 0xf0-0xff                            Free. | 266   // 0x74-0x7f            Repeat last word (subtract 0x73 to get the count). | 
|  | 267   static const int kMaxRepeats = 0x7f - 0x73; | 
|  | 268   static int CodeForRepeats(int repeats) { | 
|  | 269     ASSERT(repeats >= 1 && repeats <= kMaxRepeats); | 
|  | 270     return 0x73 + repeats; | 
|  | 271   } | 
|  | 272   static int RepeatsForCode(int byte_code) { | 
|  | 273     ASSERT(byte_code >= kConstantRepeat && byte_code <= 0x7f); | 
|  | 274     return byte_code - 0x73; | 
|  | 275   } | 
|  | 276   static const int kRootArrayLowConstants = 0xb0; | 
|  | 277   // 0xb0-0xbf            Things from the first 16 elements of the root array. | 
|  | 278   static const int kRootArrayHighConstants = 0xf0; | 
|  | 279   // 0xf0-0xff            Things from the next 16 elements of the root array. | 
|  | 280   static const int kRootArrayNumberOfConstantEncodings = 0x20; | 
|  | 281   static const int kRootArrayNumberOfLowConstantEncodings = 0x10; | 
|  | 282   static int RootArrayConstantFromByteCode(int byte_code) { | 
|  | 283     int constant = (byte_code & 0xf) | ((byte_code & 0x40) >> 2); | 
|  | 284     ASSERT(constant >= 0 && constant < kRootArrayNumberOfConstantEncodings); | 
|  | 285     return constant; | 
|  | 286   } | 
| 285 | 287 | 
| 286 | 288 | 
| 287   static const int kLargeData = LAST_SPACE; | 289   static const int kLargeData = LAST_SPACE; | 
| 288   static const int kLargeCode = kLargeData + 1; | 290   static const int kLargeCode = kLargeData + 1; | 
| 289   static const int kLargeFixedArray = kLargeCode + 1; | 291   static const int kLargeFixedArray = kLargeCode + 1; | 
| 290   static const int kNumberOfSpaces = kLargeFixedArray + 1; | 292   static const int kNumberOfSpaces = kLargeFixedArray + 1; | 
| 291   static const int kAnyOldSpace = -1; | 293   static const int kAnyOldSpace = -1; | 
| 292 | 294 | 
| 293   // A bitmask for getting the space out of an instruction. | 295   // A bitmask for getting the space out of an instruction. | 
| 294   static const int kSpaceMask = 15; | 296   static const int kSpaceMask = 15; | 
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 468     } | 470     } | 
| 469     serialization_enabled_ = true; | 471     serialization_enabled_ = true; | 
| 470   } | 472   } | 
| 471 | 473 | 
| 472   static void Disable() { serialization_enabled_ = false; } | 474   static void Disable() { serialization_enabled_ = false; } | 
| 473   // Call this when you have made use of the fact that there is no serialization | 475   // Call this when you have made use of the fact that there is no serialization | 
| 474   // going on. | 476   // going on. | 
| 475   static void TooLateToEnableNow() { too_late_to_enable_now_ = true; } | 477   static void TooLateToEnableNow() { too_late_to_enable_now_ = true; } | 
| 476   static bool enabled() { return serialization_enabled_; } | 478   static bool enabled() { return serialization_enabled_; } | 
| 477   SerializationAddressMapper* address_mapper() { return &address_mapper_; } | 479   SerializationAddressMapper* address_mapper() { return &address_mapper_; } | 
|  | 480   void PutRoot( | 
|  | 481       int index, HeapObject* object, HowToCode how, WhereToPoint where); | 
| 478 #ifdef DEBUG | 482 #ifdef DEBUG | 
| 479   virtual void Synchronize(const char* tag); | 483   virtual void Synchronize(const char* tag); | 
| 480 #endif | 484 #endif | 
| 481 | 485 | 
| 482  protected: | 486  protected: | 
| 483   static const int kInvalidRootIndex = -1; | 487   static const int kInvalidRootIndex = -1; | 
| 484   virtual int RootIndex(HeapObject* heap_object) = 0; | 488 | 
|  | 489   int RootIndex(HeapObject* heap_object); | 
| 485   virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) = 0; | 490   virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) = 0; | 
|  | 491   intptr_t root_index_wave_front() { return root_index_wave_front_; } | 
|  | 492   void set_root_index_wave_front(intptr_t value) { | 
|  | 493     root_index_wave_front_ = value; | 
|  | 494   } | 
| 486 | 495 | 
| 487   class ObjectSerializer : public ObjectVisitor { | 496   class ObjectSerializer : public ObjectVisitor { | 
| 488    public: | 497    public: | 
| 489     ObjectSerializer(Serializer* serializer, | 498     ObjectSerializer(Serializer* serializer, | 
| 490                      Object* o, | 499                      Object* o, | 
| 491                      SnapshotByteSink* sink, | 500                      SnapshotByteSink* sink, | 
| 492                      HowToCode how_to_code, | 501                      HowToCode how_to_code, | 
| 493                      WhereToPoint where_to_point) | 502                      WhereToPoint where_to_point) | 
| 494       : serializer_(serializer), | 503       : serializer_(serializer), | 
| 495         object_(HeapObject::cast(o)), | 504         object_(HeapObject::cast(o)), | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 551   // sense in large object space. | 560   // sense in large object space. | 
| 552   int fullness_[LAST_SPACE + 1]; | 561   int fullness_[LAST_SPACE + 1]; | 
| 553   SnapshotByteSink* sink_; | 562   SnapshotByteSink* sink_; | 
| 554   int current_root_index_; | 563   int current_root_index_; | 
| 555   ExternalReferenceEncoder* external_reference_encoder_; | 564   ExternalReferenceEncoder* external_reference_encoder_; | 
| 556   static bool serialization_enabled_; | 565   static bool serialization_enabled_; | 
| 557   // Did we already make use of the fact that serialization was not enabled? | 566   // Did we already make use of the fact that serialization was not enabled? | 
| 558   static bool too_late_to_enable_now_; | 567   static bool too_late_to_enable_now_; | 
| 559   int large_object_total_; | 568   int large_object_total_; | 
| 560   SerializationAddressMapper address_mapper_; | 569   SerializationAddressMapper address_mapper_; | 
|  | 570   intptr_t root_index_wave_front_; | 
| 561 | 571 | 
| 562   friend class ObjectSerializer; | 572   friend class ObjectSerializer; | 
| 563   friend class Deserializer; | 573   friend class Deserializer; | 
| 564 | 574 | 
| 565   DISALLOW_COPY_AND_ASSIGN(Serializer); | 575   DISALLOW_COPY_AND_ASSIGN(Serializer); | 
| 566 }; | 576 }; | 
| 567 | 577 | 
| 568 | 578 | 
| 569 class PartialSerializer : public Serializer { | 579 class PartialSerializer : public Serializer { | 
| 570  public: | 580  public: | 
| 571   PartialSerializer(Serializer* startup_snapshot_serializer, | 581   PartialSerializer(Serializer* startup_snapshot_serializer, | 
| 572                     SnapshotByteSink* sink) | 582                     SnapshotByteSink* sink) | 
| 573     : Serializer(sink), | 583     : Serializer(sink), | 
| 574       startup_serializer_(startup_snapshot_serializer) { | 584       startup_serializer_(startup_snapshot_serializer) { | 
|  | 585     set_root_index_wave_front(Heap::kStrongRootListLength); | 
| 575   } | 586   } | 
| 576 | 587 | 
| 577   // Serialize the objects reachable from a single object pointer. | 588   // Serialize the objects reachable from a single object pointer. | 
| 578   virtual void Serialize(Object** o); | 589   virtual void Serialize(Object** o); | 
| 579   virtual void SerializeObject(Object* o, | 590   virtual void SerializeObject(Object* o, | 
| 580                                HowToCode how_to_code, | 591                                HowToCode how_to_code, | 
| 581                                WhereToPoint where_to_point); | 592                                WhereToPoint where_to_point); | 
| 582 | 593 | 
| 583  protected: | 594  protected: | 
| 584   virtual int RootIndex(HeapObject* o); |  | 
| 585   virtual int PartialSnapshotCacheIndex(HeapObject* o); | 595   virtual int PartialSnapshotCacheIndex(HeapObject* o); | 
| 586   virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { | 596   virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { | 
| 587     // Scripts should be referred only through shared function infos.  We can't | 597     // Scripts should be referred only through shared function infos.  We can't | 
| 588     // allow them to be part of the partial snapshot because they contain a | 598     // allow them to be part of the partial snapshot because they contain a | 
| 589     // unique ID, and deserializing several partial snapshots containing script | 599     // unique ID, and deserializing several partial snapshots containing script | 
| 590     // would cause dupes. | 600     // would cause dupes. | 
| 591     ASSERT(!o->IsScript()); | 601     ASSERT(!o->IsScript()); | 
| 592     return o->IsString() || o->IsSharedFunctionInfo() || | 602     return o->IsString() || o->IsSharedFunctionInfo() || | 
| 593            o->IsHeapNumber() || o->IsCode() || | 603            o->IsHeapNumber() || o->IsCode() || | 
| 594            o->IsSerializedScopeInfo() || | 604            o->IsSerializedScopeInfo() || | 
| 595            o->map() == HEAP->fixed_cow_array_map(); | 605            o->map() == HEAP->fixed_cow_array_map(); | 
| 596   } | 606   } | 
| 597 | 607 | 
| 598  private: | 608  private: | 
| 599   Serializer* startup_serializer_; | 609   Serializer* startup_serializer_; | 
| 600   DISALLOW_COPY_AND_ASSIGN(PartialSerializer); | 610   DISALLOW_COPY_AND_ASSIGN(PartialSerializer); | 
| 601 }; | 611 }; | 
| 602 | 612 | 
| 603 | 613 | 
| 604 class StartupSerializer : public Serializer { | 614 class StartupSerializer : public Serializer { | 
| 605  public: | 615  public: | 
| 606   explicit StartupSerializer(SnapshotByteSink* sink) : Serializer(sink) { | 616   explicit StartupSerializer(SnapshotByteSink* sink) : Serializer(sink) { | 
| 607     // Clear the cache of objects used by the partial snapshot.  After the | 617     // Clear the cache of objects used by the partial snapshot.  After the | 
| 608     // strong roots have been serialized we can create a partial snapshot | 618     // strong roots have been serialized we can create a partial snapshot | 
| 609     // which will repopulate the cache with objects neede by that partial | 619     // which will repopulate the cache with objects needed by that partial | 
| 610     // snapshot. | 620     // snapshot. | 
| 611     Isolate::Current()->set_serialize_partial_snapshot_cache_length(0); | 621     Isolate::Current()->set_serialize_partial_snapshot_cache_length(0); | 
| 612   } | 622   } | 
| 613   // Serialize the current state of the heap.  The order is: | 623   // Serialize the current state of the heap.  The order is: | 
| 614   // 1) Strong references. | 624   // 1) Strong references. | 
| 615   // 2) Partial snapshot cache. | 625   // 2) Partial snapshot cache. | 
| 616   // 3) Weak references (eg the symbol table). | 626   // 3) Weak references (eg the symbol table). | 
| 617   virtual void SerializeStrongReferences(); | 627   virtual void SerializeStrongReferences(); | 
| 618   virtual void SerializeObject(Object* o, | 628   virtual void SerializeObject(Object* o, | 
| 619                                HowToCode how_to_code, | 629                                HowToCode how_to_code, | 
| 620                                WhereToPoint where_to_point); | 630                                WhereToPoint where_to_point); | 
| 621   void SerializeWeakReferences(); | 631   void SerializeWeakReferences(); | 
| 622   void Serialize() { | 632   void Serialize() { | 
| 623     SerializeStrongReferences(); | 633     SerializeStrongReferences(); | 
| 624     SerializeWeakReferences(); | 634     SerializeWeakReferences(); | 
| 625   } | 635   } | 
| 626 | 636 | 
| 627  private: | 637  private: | 
| 628   virtual int RootIndex(HeapObject* o) { return kInvalidRootIndex; } |  | 
| 629   virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { | 638   virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { | 
| 630     return false; | 639     return false; | 
| 631   } | 640   } | 
| 632 }; | 641 }; | 
| 633 | 642 | 
| 634 | 643 | 
| 635 } }  // namespace v8::internal | 644 } }  // namespace v8::internal | 
| 636 | 645 | 
| 637 #endif  // V8_SERIALIZE_H_ | 646 #endif  // V8_SERIALIZE_H_ | 
| OLD | NEW | 
|---|