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 |