| 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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 }; | 141 }; |
| 142 | 142 |
| 143 | 143 |
| 144 // It is very common to have a reference to objects at certain offsets in the | 144 // It is very common to have a reference to objects at certain offsets in the |
| 145 // heap. These offsets have been determined experimentally. We code | 145 // heap. These offsets have been determined experimentally. We code |
| 146 // references to such objects in a single byte that encodes the way the pointer | 146 // references to such objects in a single byte that encodes the way the pointer |
| 147 // is written (only plain pointers allowed), the space number and the offset. | 147 // is written (only plain pointers allowed), the space number and the offset. |
| 148 // This only works for objects in the first page of a space. Don't use this for | 148 // This only works for objects in the first page of a space. Don't use this for |
| 149 // things in newspace since it bypasses the write barrier. | 149 // things in newspace since it bypasses the write barrier. |
| 150 | 150 |
| 151 RLYSTC const int k64 = (sizeof(uintptr_t) - 4) / 4; | 151 static const int k64 = (sizeof(uintptr_t) - 4) / 4; |
| 152 | 152 |
| 153 #define COMMON_REFERENCE_PATTERNS(f) \ | 153 #define COMMON_REFERENCE_PATTERNS(f) \ |
| 154 f(kNumberOfSpaces, 2, (11 - k64)) \ | 154 f(kNumberOfSpaces, 2, (11 - k64)) \ |
| 155 f((kNumberOfSpaces + 1), 2, 0) \ | 155 f((kNumberOfSpaces + 1), 2, 0) \ |
| 156 f((kNumberOfSpaces + 2), 2, (142 - 16 * k64)) \ | 156 f((kNumberOfSpaces + 2), 2, (142 - 16 * k64)) \ |
| 157 f((kNumberOfSpaces + 3), 2, (74 - 15 * k64)) \ | 157 f((kNumberOfSpaces + 3), 2, (74 - 15 * k64)) \ |
| 158 f((kNumberOfSpaces + 4), 2, 5) \ | 158 f((kNumberOfSpaces + 4), 2, 5) \ |
| 159 f((kNumberOfSpaces + 5), 1, 135) \ | 159 f((kNumberOfSpaces + 5), 1, 135) \ |
| 160 f((kNumberOfSpaces + 6), 2, (228 - 39 * k64)) | 160 f((kNumberOfSpaces + 6), 2, (228 - 39 * k64)) |
| 161 | 161 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 174 f(12, 24) \ | 174 f(12, 24) \ |
| 175 f(13, 28) \ | 175 f(13, 28) \ |
| 176 f(14, 32) \ | 176 f(14, 32) \ |
| 177 f(15, 36) | 177 f(15, 36) |
| 178 | 178 |
| 179 // The Serializer/Deserializer class is a common superclass for Serializer and | 179 // The Serializer/Deserializer class is a common superclass for Serializer and |
| 180 // Deserializer which is used to store common constants and methods used by | 180 // Deserializer which is used to store common constants and methods used by |
| 181 // both. | 181 // both. |
| 182 class SerializerDeserializer: public ObjectVisitor { | 182 class SerializerDeserializer: public ObjectVisitor { |
| 183 public: | 183 public: |
| 184 RLYSTC void Iterate(ObjectVisitor* visitor); | 184 static void Iterate(ObjectVisitor* visitor); |
| 185 RLYSTC void SetSnapshotCacheSize(int size); | 185 static void SetSnapshotCacheSize(int size); |
| 186 | 186 |
| 187 protected: | 187 protected: |
| 188 // Where the pointed-to object can be found: | 188 // Where the pointed-to object can be found: |
| 189 enum Where { | 189 enum Where { |
| 190 kNewObject = 0, // Object is next in snapshot. | 190 kNewObject = 0, // Object is next in snapshot. |
| 191 // 1-8 One per space. | 191 // 1-8 One per space. |
| 192 kRootArray = 0x9, // Object is found in root array. | 192 kRootArray = 0x9, // Object is found in root array. |
| 193 kPartialSnapshotCache = 0xa, // Object is in the cache. | 193 kPartialSnapshotCache = 0xa, // Object is in the cache. |
| 194 kExternalReference = 0xb, // Pointer to an external reference. | 194 kExternalReference = 0xb, // Pointer to an external reference. |
| 195 // 0xc-0xf Free. | 195 // 0xc-0xf Free. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 213 | 213 |
| 214 // Where to point within the object. | 214 // Where to point within the object. |
| 215 enum WhereToPoint { | 215 enum WhereToPoint { |
| 216 kStartOfObject = 0, | 216 kStartOfObject = 0, |
| 217 kFirstInstruction = 0x80, | 217 kFirstInstruction = 0x80, |
| 218 kWhereToPointMask = 0x80 | 218 kWhereToPointMask = 0x80 |
| 219 }; | 219 }; |
| 220 | 220 |
| 221 // Misc. | 221 // Misc. |
| 222 // Raw data to be copied from the snapshot. | 222 // Raw data to be copied from the snapshot. |
| 223 RLYSTC const int kRawData = 0x30; | 223 static const int kRawData = 0x30; |
| 224 // Some common raw lengths: 0x31-0x3f | 224 // Some common raw lengths: 0x31-0x3f |
| 225 // A tag emitted at strategic points in the snapshot to delineate sections. | 225 // A tag emitted at strategic points in the snapshot to delineate sections. |
| 226 // If the deserializer does not find these at the expected moments then it | 226 // If the deserializer does not find these at the expected moments then it |
| 227 // is an indication that the snapshot and the VM do not fit together. | 227 // is an indication that the snapshot and the VM do not fit together. |
| 228 // Examine the build process for architecture, version or configuration | 228 // Examine the build process for architecture, version or configuration |
| 229 // mismatches. | 229 // mismatches. |
| 230 RLYSTC const int kSynchronize = 0x70; | 230 static const int kSynchronize = 0x70; |
| 231 // Used for the source code of the natives, which is in the executable, but | 231 // Used for the source code of the natives, which is in the executable, but |
| 232 // is referred to from external strings in the snapshot. | 232 // is referred to from external strings in the snapshot. |
| 233 RLYSTC const int kNativesStringResource = 0x71; | 233 static const int kNativesStringResource = 0x71; |
| 234 RLYSTC const int kNewPage = 0x72; | 234 static const int kNewPage = 0x72; |
| 235 // 0x73-0x7f Free. | 235 // 0x73-0x7f Free. |
| 236 // 0xb0-0xbf Free. | 236 // 0xb0-0xbf Free. |
| 237 // 0xf0-0xff Free. | 237 // 0xf0-0xff Free. |
| 238 | 238 |
| 239 | 239 |
| 240 RLYSTC const int kLargeData = LAST_SPACE; | 240 static const int kLargeData = LAST_SPACE; |
| 241 RLYSTC const int kLargeCode = kLargeData + 1; | 241 static const int kLargeCode = kLargeData + 1; |
| 242 RLYSTC const int kLargeFixedArray = kLargeCode + 1; | 242 static const int kLargeFixedArray = kLargeCode + 1; |
| 243 RLYSTC const int kNumberOfSpaces = kLargeFixedArray + 1; | 243 static const int kNumberOfSpaces = kLargeFixedArray + 1; |
| 244 RLYSTC const int kAnyOldSpace = -1; | 244 static const int kAnyOldSpace = -1; |
| 245 | 245 |
| 246 // A bitmask for getting the space out of an instruction. | 246 // A bitmask for getting the space out of an instruction. |
| 247 RLYSTC const int kSpaceMask = 15; | 247 static const int kSpaceMask = 15; |
| 248 | 248 |
| 249 RLYSTC inline bool SpaceIsLarge(int space) { return space >= kLargeData; } | 249 static inline bool SpaceIsLarge(int space) { return space >= kLargeData; } |
| 250 RLYSTC inline bool SpaceIsPaged(int space) { | 250 static inline bool SpaceIsPaged(int space) { |
| 251 return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE; | 251 return space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE; |
| 252 } | 252 } |
| 253 }; | 253 }; |
| 254 | 254 |
| 255 | 255 |
| 256 int SnapshotByteSource::GetInt() { | 256 int SnapshotByteSource::GetInt() { |
| 257 // A little unwind to catch the really small ints. | 257 // A little unwind to catch the really small ints. |
| 258 int snapshot_byte = Get(); | 258 int snapshot_byte = Get(); |
| 259 if ((snapshot_byte & 0x80) == 0) { | 259 if ((snapshot_byte & 0x80) == 0) { |
| 260 return snapshot_byte; | 260 return snapshot_byte; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 } | 373 } |
| 374 | 374 |
| 375 void AddMapping(HeapObject* obj, int to) { | 375 void AddMapping(HeapObject* obj, int to) { |
| 376 ASSERT(!IsMapped(obj)); | 376 ASSERT(!IsMapped(obj)); |
| 377 HashMap::Entry* entry = | 377 HashMap::Entry* entry = |
| 378 serialization_map_->Lookup(Key(obj), Hash(obj), true); | 378 serialization_map_->Lookup(Key(obj), Hash(obj), true); |
| 379 entry->value = Value(to); | 379 entry->value = Value(to); |
| 380 } | 380 } |
| 381 | 381 |
| 382 private: | 382 private: |
| 383 RLYSTC bool SerializationMatchFun(void* key1, void* key2) { | 383 static bool SerializationMatchFun(void* key1, void* key2) { |
| 384 return key1 == key2; | 384 return key1 == key2; |
| 385 } | 385 } |
| 386 | 386 |
| 387 RLYSTC uint32_t Hash(HeapObject* obj) { | 387 static uint32_t Hash(HeapObject* obj) { |
| 388 return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address())); | 388 return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address())); |
| 389 } | 389 } |
| 390 | 390 |
| 391 RLYSTC void* Key(HeapObject* obj) { | 391 static void* Key(HeapObject* obj) { |
| 392 return reinterpret_cast<void*>(obj->address()); | 392 return reinterpret_cast<void*>(obj->address()); |
| 393 } | 393 } |
| 394 | 394 |
| 395 RLYSTC void* Value(int v) { | 395 static void* Value(int v) { |
| 396 return reinterpret_cast<void*>(v); | 396 return reinterpret_cast<void*>(v); |
| 397 } | 397 } |
| 398 | 398 |
| 399 HashMap* serialization_map_; | 399 HashMap* serialization_map_; |
| 400 AssertNoAllocation* no_allocation_; | 400 AssertNoAllocation* no_allocation_; |
| 401 DISALLOW_COPY_AND_ASSIGN(SerializationAddressMapper); | 401 DISALLOW_COPY_AND_ASSIGN(SerializationAddressMapper); |
| 402 }; | 402 }; |
| 403 | 403 |
| 404 | 404 |
| 405 // There can be only one serializer per V8 process. | 405 // There can be only one serializer per V8 process. |
| 406 STATIC_CLASS Serializer : public SerializerDeserializer { | 406 class Serializer : public SerializerDeserializer { |
| 407 public: | 407 public: |
| 408 explicit Serializer(SnapshotByteSink* sink); | 408 explicit Serializer(SnapshotByteSink* sink); |
| 409 ~Serializer(); | 409 ~Serializer(); |
| 410 void VisitPointers(Object** start, Object** end); | 410 void VisitPointers(Object** start, Object** end); |
| 411 // You can call this after serialization to find out how much space was used | 411 // You can call this after serialization to find out how much space was used |
| 412 // in each space. | 412 // in each space. |
| 413 int CurrentAllocationAddress(int space) { | 413 int CurrentAllocationAddress(int space) { |
| 414 if (SpaceIsLarge(space)) return large_object_total_; | 414 if (SpaceIsLarge(space)) return large_object_total_; |
| 415 return fullness_[space]; | 415 return fullness_[space]; |
| 416 } | 416 } |
| 417 | 417 |
| 418 RLYSTC void Enable() { | 418 static void Enable() { |
| 419 if (!serialization_enabled_) { | 419 if (!serialization_enabled_) { |
| 420 ASSERT(!too_late_to_enable_now_); | 420 ASSERT(!too_late_to_enable_now_); |
| 421 } | 421 } |
| 422 serialization_enabled_ = true; | 422 serialization_enabled_ = true; |
| 423 } | 423 } |
| 424 | 424 |
| 425 RLYSTC void Disable() { serialization_enabled_ = false; } | 425 static void Disable() { serialization_enabled_ = false; } |
| 426 // Call this when you have made use of the fact that there is no serialization | 426 // Call this when you have made use of the fact that there is no serialization |
| 427 // going on. | 427 // going on. |
| 428 RLYSTC void TooLateToEnableNow() { too_late_to_enable_now_ = true; } | 428 static void TooLateToEnableNow() { too_late_to_enable_now_ = true; } |
| 429 RLYSTC bool enabled() { return serialization_enabled_; } | 429 static bool enabled() { return serialization_enabled_; } |
| 430 SerializationAddressMapper* address_mapper() { return &address_mapper_; } | 430 SerializationAddressMapper* address_mapper() { return &address_mapper_; } |
| 431 #ifdef DEBUG | 431 #ifdef DEBUG |
| 432 virtual void Synchronize(const char* tag); | 432 virtual void Synchronize(const char* tag); |
| 433 #endif | 433 #endif |
| 434 | 434 |
| 435 protected: | 435 protected: |
| 436 RLYSTC const int kInvalidRootIndex = -1; | 436 static const int kInvalidRootIndex = -1; |
| 437 virtual int RootIndex(HeapObject* heap_object) = 0; | 437 virtual int RootIndex(HeapObject* heap_object) = 0; |
| 438 virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) = 0; | 438 virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) = 0; |
| 439 | 439 |
| 440 class ObjectSerializer : public ObjectVisitor { | 440 class ObjectSerializer : public ObjectVisitor { |
| 441 public: | 441 public: |
| 442 ObjectSerializer(Serializer* serializer, | 442 ObjectSerializer(Serializer* serializer, |
| 443 Object* o, | 443 Object* o, |
| 444 SnapshotByteSink* sink, | 444 SnapshotByteSink* sink, |
| 445 HowToCode how_to_code, | 445 HowToCode how_to_code, |
| 446 WhereToPoint where_to_point) | 446 WhereToPoint where_to_point) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 void SerializeReferenceToPreviousObject( | 481 void SerializeReferenceToPreviousObject( |
| 482 int space, | 482 int space, |
| 483 int address, | 483 int address, |
| 484 HowToCode how_to_code, | 484 HowToCode how_to_code, |
| 485 WhereToPoint where_to_point); | 485 WhereToPoint where_to_point); |
| 486 void InitializeAllocators(); | 486 void InitializeAllocators(); |
| 487 // This will return the space for an object. If the object is in large | 487 // This will return the space for an object. If the object is in large |
| 488 // object space it may return kLargeCode or kLargeFixedArray in order | 488 // object space it may return kLargeCode or kLargeFixedArray in order |
| 489 // to indicate to the deserializer what kind of large object allocation | 489 // to indicate to the deserializer what kind of large object allocation |
| 490 // to make. | 490 // to make. |
| 491 RLYSTC int SpaceOfObject(HeapObject* object); | 491 static int SpaceOfObject(HeapObject* object); |
| 492 // This just returns the space of the object. It will return LO_SPACE | 492 // This just returns the space of the object. It will return LO_SPACE |
| 493 // for all large objects since you can't check the type of the object | 493 // for all large objects since you can't check the type of the object |
| 494 // once the map has been used for the serialization address. | 494 // once the map has been used for the serialization address. |
| 495 RLYSTC int SpaceOfAlreadySerializedObject(HeapObject* object); | 495 static int SpaceOfAlreadySerializedObject(HeapObject* object); |
| 496 int Allocate(int space, int size, bool* new_page_started); | 496 int Allocate(int space, int size, bool* new_page_started); |
| 497 int EncodeExternalReference(Address addr) { | 497 int EncodeExternalReference(Address addr) { |
| 498 return external_reference_encoder_->Encode(addr); | 498 return external_reference_encoder_->Encode(addr); |
| 499 } | 499 } |
| 500 | 500 |
| 501 // Keep track of the fullness of each space in order to generate | 501 // Keep track of the fullness of each space in order to generate |
| 502 // relative addresses for back references. Large objects are | 502 // relative addresses for back references. Large objects are |
| 503 // just numbered sequentially since relative addresses make no | 503 // just numbered sequentially since relative addresses make no |
| 504 // sense in large object space. | 504 // sense in large object space. |
| 505 int fullness_[LAST_SPACE + 1]; | 505 int fullness_[LAST_SPACE + 1]; |
| 506 SnapshotByteSink* sink_; | 506 SnapshotByteSink* sink_; |
| 507 int current_root_index_; | 507 int current_root_index_; |
| 508 ExternalReferenceEncoder* external_reference_encoder_; | 508 ExternalReferenceEncoder* external_reference_encoder_; |
| 509 RLYSTC bool serialization_enabled_; | 509 static bool serialization_enabled_; |
| 510 // Did we already make use of the fact that serialization was not enabled? | 510 // Did we already make use of the fact that serialization was not enabled? |
| 511 RLYSTC bool too_late_to_enable_now_; | 511 static bool too_late_to_enable_now_; |
| 512 int large_object_total_; | 512 int large_object_total_; |
| 513 SerializationAddressMapper address_mapper_; | 513 SerializationAddressMapper address_mapper_; |
| 514 | 514 |
| 515 friend class ObjectSerializer; | 515 friend class ObjectSerializer; |
| 516 friend class Deserializer; | 516 friend class Deserializer; |
| 517 | 517 |
| 518 DISALLOW_COPY_AND_ASSIGN(Serializer); | 518 DISALLOW_COPY_AND_ASSIGN(Serializer); |
| 519 }; | 519 }; |
| 520 | 520 |
| 521 | 521 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 virtual int RootIndex(HeapObject* o) { return kInvalidRootIndex; } | 580 virtual int RootIndex(HeapObject* o) { return kInvalidRootIndex; } |
| 581 virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { | 581 virtual bool ShouldBeInThePartialSnapshotCache(HeapObject* o) { |
| 582 return false; | 582 return false; |
| 583 } | 583 } |
| 584 }; | 584 }; |
| 585 | 585 |
| 586 | 586 |
| 587 } } // namespace v8::internal | 587 } } // namespace v8::internal |
| 588 | 588 |
| 589 #endif // V8_SERIALIZE_H_ | 589 #endif // V8_SERIALIZE_H_ |
| OLD | NEW |