| 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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 | 130 |
| 131 int position() { return position_; } | 131 int position() { return position_; } |
| 132 | 132 |
| 133 private: | 133 private: |
| 134 const byte* data_; | 134 const byte* data_; |
| 135 int length_; | 135 int length_; |
| 136 int position_; | 136 int position_; |
| 137 }; | 137 }; |
| 138 | 138 |
| 139 | 139 |
| 140 // It is very common to have a reference to the object at word 10 in space 2, | 140 // It is very common to have a reference to objects at certain offsets in the |
| 141 // the object at word 5 in space 2 and the object at word 28 in space 4. This | 141 // heap. These offsets have been determined experimentally. We code |
| 142 // only works for objects in the first page of a space. | 142 // references to such objects in a single byte that encodes the way the pointer |
| 143 #define COMMON_REFERENCE_PATTERNS(f) \ | 143 // is written (only plain pointers allowed), the space number and the offset. |
| 144 f(kNumberOfSpaces, 2, 10) \ | 144 // This only works for objects in the first page of a space. Don't use this for |
| 145 f(kNumberOfSpaces + 1, 2, 5) \ | 145 // things in newspace since it bypasses the write barrier. |
| 146 f(kNumberOfSpaces + 2, 4, 28) \ | 146 |
| 147 f(kNumberOfSpaces + 3, 2, 21) \ | 147 static const int k64 = (sizeof(uintptr_t) - 4) / 4; |
| 148 f(kNumberOfSpaces + 4, 2, 98) \ | 148 |
| 149 f(kNumberOfSpaces + 5, 2, 67) \ | 149 #define COMMON_REFERENCE_PATTERNS(f) \ |
| 150 f(kNumberOfSpaces + 6, 4, 132) | 150 f(kNumberOfSpaces, 2, 11 - k64) \ |
| 151 f(kNumberOfSpaces + 1, 2, 0) \ |
| 152 f(kNumberOfSpaces + 2, 2, 142 - 16 * k64) \ |
| 153 f(kNumberOfSpaces + 3, 2, 74 - 15 * k64) \ |
| 154 f(kNumberOfSpaces + 4, 2, 5) \ |
| 155 f(kNumberOfSpaces + 5, 1, 135) \ |
| 156 f(kNumberOfSpaces + 6, 2, 228 - 39 * k64) |
| 151 | 157 |
| 152 #define COMMON_RAW_LENGTHS(f) \ | 158 #define COMMON_RAW_LENGTHS(f) \ |
| 153 f(1, 1) \ | 159 f(1, 1) \ |
| 154 f(2, 2) \ | 160 f(2, 2) \ |
| 155 f(3, 3) \ | 161 f(3, 3) \ |
| 156 f(4, 4) \ | 162 f(4, 4) \ |
| 157 f(5, 5) \ | 163 f(5, 5) \ |
| 158 f(6, 6) \ | 164 f(6, 6) \ |
| 159 f(7, 7) \ | 165 f(7, 7) \ |
| 160 f(8, 8) \ | 166 f(8, 8) \ |
| 161 f(9, 12) \ | 167 f(9, 12) \ |
| 162 f(10, 16) \ | 168 f(10, 16) \ |
| 163 f(11, 20) \ | 169 f(11, 20) \ |
| 164 f(12, 24) \ | 170 f(12, 24) \ |
| 165 f(13, 28) \ | 171 f(13, 28) \ |
| 166 f(14, 32) \ | 172 f(14, 32) \ |
| 167 f(15, 36) | 173 f(15, 36) |
| 168 | 174 |
| 169 // The Serializer/Deserializer class is a common superclass for Serializer and | 175 // The Serializer/Deserializer class is a common superclass for Serializer and |
| 170 // Deserializer which is used to store common constants and methods used by | 176 // Deserializer which is used to store common constants and methods used by |
| 171 // both. | 177 // both. |
| 172 class SerializerDeserializer: public ObjectVisitor { | 178 class SerializerDeserializer: public ObjectVisitor { |
| 173 public: | 179 public: |
| 174 static void Iterate(ObjectVisitor* visitor); | 180 static void Iterate(ObjectVisitor* visitor); |
| 175 static void SetSnapshotCacheSize(int size); | 181 static void SetSnapshotCacheSize(int size); |
| 176 | 182 |
| 177 protected: | 183 protected: |
| 178 enum DataType { | 184 // Where the pointed-to object can be found: |
| 179 RAW_DATA_SERIALIZATION = 0, | 185 enum Where { |
| 180 // And 15 common raw lengths. | 186 kNewObject = 0, // Object is next in snapshot. |
| 181 OBJECT_SERIALIZATION = 16, | 187 // 1-8 One per space. |
| 182 // One variant per space. | 188 kRootArray = 0x9, // Object is found in root array. |
| 183 CODE_OBJECT_SERIALIZATION = 25, | 189 kPartialSnapshotCache = 0xa, // Object is in the cache. |
| 184 // One per space (only code spaces in use). | 190 kExternalReference = 0xb, // Pointer to an external reference. |
| 185 EXTERNAL_REFERENCE_SERIALIZATION = 34, | 191 // 0xc-0xf Free. |
| 186 EXTERNAL_BRANCH_TARGET_SERIALIZATION = 35, | 192 kBackref = 0x10, // Object is described relative to end. |
| 187 SYNCHRONIZE = 36, | 193 // 0x11-0x18 One per space. |
| 188 START_NEW_PAGE_SERIALIZATION = 37, | 194 // 0x19-0x1f Common backref offsets. |
| 189 NATIVES_STRING_RESOURCE = 38, | 195 kFromStart = 0x20, // Object is described relative to start. |
| 190 ROOT_SERIALIZATION = 39, | 196 // 0x21-0x28 One per space. |
| 191 PARTIAL_SNAPSHOT_CACHE_ENTRY = 40, | 197 // 0x29-0x2f Free. |
| 192 // Free: 41-47. | 198 // 0x30-0x3f Used by misc tags below. |
| 193 BACKREF_SERIALIZATION = 48, | 199 kPointedToMask = 0x3f |
| 194 // One per space, must be kSpaceMask aligned. | |
| 195 // Free: 57-63. | |
| 196 REFERENCE_SERIALIZATION = 64, | |
| 197 // One per space and common references. Must be kSpaceMask aligned. | |
| 198 CODE_BACKREF_SERIALIZATION = 80, | |
| 199 // One per space, must be kSpaceMask aligned. | |
| 200 // Free: 89-95. | |
| 201 CODE_REFERENCE_SERIALIZATION = 96 | |
| 202 // One per space, must be kSpaceMask aligned. | |
| 203 // Free: 105-255. | |
| 204 }; | 200 }; |
| 201 |
| 202 // How to code the pointer to the object. |
| 203 enum HowToCode { |
| 204 kPlain = 0, // Straight pointer. |
| 205 // What this means depends on the architecture: |
| 206 kFromCode = 0x40, // A pointer inlined in code. |
| 207 kHowToCodeMask = 0x40 |
| 208 }; |
| 209 |
| 210 // Where to point within the object. |
| 211 enum WhereToPoint { |
| 212 kStartOfObject = 0, |
| 213 kFirstInstruction = 0x80, |
| 214 kWhereToPointMask = 0x80 |
| 215 }; |
| 216 |
| 217 // Misc. |
| 218 // Raw data to be copied from the snapshot. |
| 219 static const int kRawData = 0x30; |
| 220 // Some common raw lengths: 0x31-0x3f |
| 221 // A tag emitted at strategic points in the snapshot to delineate sections. |
| 222 // If the deserializer does not find these at the expected moments then it |
| 223 // is an indication that the snapshot and the VM do not fit together. |
| 224 // Examine the build process for architecture, version or configuration |
| 225 // mismatches. |
| 226 static const int kSynchronize = 0x70; |
| 227 // Used for the source code of the natives, which is in the executable, but |
| 228 // is referred to from external strings in the snapshot. |
| 229 static const int kNativesStringResource = 0x71; |
| 230 static const int kNewPage = 0x72; |
| 231 // 0x73-0x7f Free. |
| 232 // 0xb0-0xbf Free. |
| 233 // 0xf0-0xff Free. |
| 234 |
| 235 |
| 205 static const int kLargeData = LAST_SPACE; | 236 static const int kLargeData = LAST_SPACE; |
| 206 static const int kLargeCode = kLargeData + 1; | 237 static const int kLargeCode = kLargeData + 1; |
| 207 static const int kLargeFixedArray = kLargeCode + 1; | 238 static const int kLargeFixedArray = kLargeCode + 1; |
| 208 static const int kNumberOfSpaces = kLargeFixedArray + 1; | 239 static const int kNumberOfSpaces = kLargeFixedArray + 1; |
| 240 static const int kAnyOldSpace = -1; |
| 209 | 241 |
| 210 // A bitmask for getting the space out of an instruction. | 242 // A bitmask for getting the space out of an instruction. |
| 211 static const int kSpaceMask = 15; | 243 static const int kSpaceMask = 15; |
| 212 | 244 |
| 213 static inline bool SpaceIsLarge(int space) { return space >= kLargeData; } | 245 static inline bool SpaceIsLarge(int space) { return space >= kLargeData; } |
| 214 static inline bool SpaceIsPaged(int space) { | 246 static inline bool SpaceIsPaged(int space) { |
| 215 return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE; | 247 return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE; |
| 216 } | 248 } |
| 217 | 249 |
| 218 static int partial_snapshot_cache_length_; | 250 static int partial_snapshot_cache_length_; |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 // Call this when you have made use of the fact that there is no serialization | 421 // Call this when you have made use of the fact that there is no serialization |
| 390 // going on. | 422 // going on. |
| 391 static void TooLateToEnableNow() { too_late_to_enable_now_ = true; } | 423 static void TooLateToEnableNow() { too_late_to_enable_now_ = true; } |
| 392 static bool enabled() { return serialization_enabled_; } | 424 static bool enabled() { return serialization_enabled_; } |
| 393 SerializationAddressMapper* address_mapper() { return &address_mapper_; } | 425 SerializationAddressMapper* address_mapper() { return &address_mapper_; } |
| 394 #ifdef DEBUG | 426 #ifdef DEBUG |
| 395 virtual void Synchronize(const char* tag); | 427 virtual void Synchronize(const char* tag); |
| 396 #endif | 428 #endif |
| 397 | 429 |
| 398 protected: | 430 protected: |
| 399 enum ReferenceRepresentation { | |
| 400 TAGGED_REPRESENTATION, // A tagged object reference. | |
| 401 CODE_TARGET_REPRESENTATION // A reference to first instruction in target. | |
| 402 }; | |
| 403 static const int kInvalidRootIndex = -1; | 431 static const int kInvalidRootIndex = -1; |
| 404 virtual int RootIndex(HeapObject* heap_object) = 0; | 432 virtual int RootIndex(HeapObject* heap_object) = 0; |
| 405 virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) = 0; | 433 virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) = 0; |
| 406 | 434 |
| 407 class ObjectSerializer : public ObjectVisitor { | 435 class ObjectSerializer : public ObjectVisitor { |
| 408 public: | 436 public: |
| 409 ObjectSerializer(Serializer* serializer, | 437 ObjectSerializer(Serializer* serializer, |
| 410 Object* o, | 438 Object* o, |
| 411 SnapshotByteSink* sink, | 439 SnapshotByteSink* sink, |
| 412 ReferenceRepresentation representation) | 440 HowToCode how_to_code, |
| 441 WhereToPoint where_to_point) |
| 413 : serializer_(serializer), | 442 : serializer_(serializer), |
| 414 object_(HeapObject::cast(o)), | 443 object_(HeapObject::cast(o)), |
| 415 sink_(sink), | 444 sink_(sink), |
| 416 reference_representation_(representation), | 445 reference_representation_(how_to_code + where_to_point), |
| 417 bytes_processed_so_far_(0) { } | 446 bytes_processed_so_far_(0) { } |
| 418 void Serialize(); | 447 void Serialize(); |
| 419 void VisitPointers(Object** start, Object** end); | 448 void VisitPointers(Object** start, Object** end); |
| 420 void VisitExternalReferences(Address* start, Address* end); | 449 void VisitExternalReferences(Address* start, Address* end); |
| 421 void VisitCodeTarget(RelocInfo* target); | 450 void VisitCodeTarget(RelocInfo* target); |
| 422 void VisitRuntimeEntry(RelocInfo* reloc); | 451 void VisitRuntimeEntry(RelocInfo* reloc); |
| 423 // Used for seralizing the external strings that hold the natives source. | 452 // Used for seralizing the external strings that hold the natives source. |
| 424 void VisitExternalAsciiString( | 453 void VisitExternalAsciiString( |
| 425 v8::String::ExternalAsciiStringResource** resource); | 454 v8::String::ExternalAsciiStringResource** resource); |
| 426 // We can't serialize a heap with external two byte strings. | 455 // We can't serialize a heap with external two byte strings. |
| 427 void VisitExternalTwoByteString( | 456 void VisitExternalTwoByteString( |
| 428 v8::String::ExternalStringResource** resource) { | 457 v8::String::ExternalStringResource** resource) { |
| 429 UNREACHABLE(); | 458 UNREACHABLE(); |
| 430 } | 459 } |
| 431 | 460 |
| 432 private: | 461 private: |
| 433 void OutputRawData(Address up_to); | 462 void OutputRawData(Address up_to); |
| 434 | 463 |
| 435 Serializer* serializer_; | 464 Serializer* serializer_; |
| 436 HeapObject* object_; | 465 HeapObject* object_; |
| 437 SnapshotByteSink* sink_; | 466 SnapshotByteSink* sink_; |
| 438 ReferenceRepresentation reference_representation_; | 467 int reference_representation_; |
| 439 int bytes_processed_so_far_; | 468 int bytes_processed_so_far_; |
| 440 }; | 469 }; |
| 441 | 470 |
| 442 virtual void SerializeObject(Object* o, | 471 virtual void SerializeObject(Object* o, |
| 443 ReferenceRepresentation representation) = 0; | 472 HowToCode how_to_code, |
| 473 WhereToPoint where_to_point) = 0; |
| 444 void SerializeReferenceToPreviousObject( | 474 void SerializeReferenceToPreviousObject( |
| 445 int space, | 475 int space, |
| 446 int address, | 476 int address, |
| 447 ReferenceRepresentation reference_representation); | 477 HowToCode how_to_code, |
| 478 WhereToPoint where_to_point); |
| 448 void InitializeAllocators(); | 479 void InitializeAllocators(); |
| 449 // This will return the space for an object. If the object is in large | 480 // This will return the space for an object. If the object is in large |
| 450 // object space it may return kLargeCode or kLargeFixedArray in order | 481 // object space it may return kLargeCode or kLargeFixedArray in order |
| 451 // to indicate to the deserializer what kind of large object allocation | 482 // to indicate to the deserializer what kind of large object allocation |
| 452 // to make. | 483 // to make. |
| 453 static int SpaceOfObject(HeapObject* object); | 484 static int SpaceOfObject(HeapObject* object); |
| 454 // This just returns the space of the object. It will return LO_SPACE | 485 // This just returns the space of the object. It will return LO_SPACE |
| 455 // for all large objects since you can't check the type of the object | 486 // for all large objects since you can't check the type of the object |
| 456 // once the map has been used for the serialization address. | 487 // once the map has been used for the serialization address. |
| 457 static int SpaceOfAlreadySerializedObject(HeapObject* object); | 488 static int SpaceOfAlreadySerializedObject(HeapObject* object); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 485 public: | 516 public: |
| 486 PartialSerializer(Serializer* startup_snapshot_serializer, | 517 PartialSerializer(Serializer* startup_snapshot_serializer, |
| 487 SnapshotByteSink* sink) | 518 SnapshotByteSink* sink) |
| 488 : Serializer(sink), | 519 : Serializer(sink), |
| 489 startup_serializer_(startup_snapshot_serializer) { | 520 startup_serializer_(startup_snapshot_serializer) { |
| 490 } | 521 } |
| 491 | 522 |
| 492 // Serialize the objects reachable from a single object pointer. | 523 // Serialize the objects reachable from a single object pointer. |
| 493 virtual void Serialize(Object** o); | 524 virtual void Serialize(Object** o); |
| 494 virtual void SerializeObject(Object* o, | 525 virtual void SerializeObject(Object* o, |
| 495 ReferenceRepresentation representation); | 526 HowToCode how_to_code, |
| 527 WhereToPoint where_to_point); |
| 496 | 528 |
| 497 protected: | 529 protected: |
| 498 virtual int RootIndex(HeapObject* o); | 530 virtual int RootIndex(HeapObject* o); |
| 499 virtual int PartialSnapshotCacheIndex(HeapObject* o); | 531 virtual int PartialSnapshotCacheIndex(HeapObject* o); |
| 500 virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { | 532 virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { |
| 501 // Scripts should be referred only through shared function infos. We can't | 533 // Scripts should be referred only through shared function infos. We can't |
| 502 // allow them to be part of the partial snapshot because they contain a | 534 // allow them to be part of the partial snapshot because they contain a |
| 503 // unique ID, and deserializing several partial snapshots containing script | 535 // unique ID, and deserializing several partial snapshots containing script |
| 504 // would cause dupes. | 536 // would cause dupes. |
| 505 ASSERT(!o->IsScript()); | 537 ASSERT(!o->IsScript()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 521 // which will repopulate the cache with objects neede by that partial | 553 // which will repopulate the cache with objects neede by that partial |
| 522 // snapshot. | 554 // snapshot. |
| 523 partial_snapshot_cache_length_ = 0; | 555 partial_snapshot_cache_length_ = 0; |
| 524 } | 556 } |
| 525 // Serialize the current state of the heap. The order is: | 557 // Serialize the current state of the heap. The order is: |
| 526 // 1) Strong references. | 558 // 1) Strong references. |
| 527 // 2) Partial snapshot cache. | 559 // 2) Partial snapshot cache. |
| 528 // 3) Weak references (eg the symbol table). | 560 // 3) Weak references (eg the symbol table). |
| 529 virtual void SerializeStrongReferences(); | 561 virtual void SerializeStrongReferences(); |
| 530 virtual void SerializeObject(Object* o, | 562 virtual void SerializeObject(Object* o, |
| 531 ReferenceRepresentation representation); | 563 HowToCode how_to_code, |
| 564 WhereToPoint where_to_point); |
| 532 void SerializeWeakReferences(); | 565 void SerializeWeakReferences(); |
| 533 void Serialize() { | 566 void Serialize() { |
| 534 SerializeStrongReferences(); | 567 SerializeStrongReferences(); |
| 535 SerializeWeakReferences(); | 568 SerializeWeakReferences(); |
| 536 } | 569 } |
| 537 | 570 |
| 538 private: | 571 private: |
| 539 virtual int RootIndex(HeapObject* o) { return kInvalidRootIndex; } | 572 virtual int RootIndex(HeapObject* o) { return kInvalidRootIndex; } |
| 540 virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { | 573 virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { |
| 541 return false; | 574 return false; |
| 542 } | 575 } |
| 543 }; | 576 }; |
| 544 | 577 |
| 545 | 578 |
| 546 } } // namespace v8::internal | 579 } } // namespace v8::internal |
| 547 | 580 |
| 548 #endif // V8_SERIALIZE_H_ | 581 #endif // V8_SERIALIZE_H_ |
| OLD | NEW |