| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_SERIALIZE_H_ | 5 #ifndef V8_SERIALIZE_H_ |
| 6 #define V8_SERIALIZE_H_ | 6 #define V8_SERIALIZE_H_ |
| 7 | 7 |
| 8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
| 9 #include "src/hashmap.h" | 9 #include "src/hashmap.h" |
| 10 #include "src/heap-profiler.h" | 10 #include "src/heap-profiler.h" |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 class SerializerDeserializer: public ObjectVisitor { | 145 class SerializerDeserializer: public ObjectVisitor { |
| 146 public: | 146 public: |
| 147 static void Iterate(Isolate* isolate, ObjectVisitor* visitor); | 147 static void Iterate(Isolate* isolate, ObjectVisitor* visitor); |
| 148 | 148 |
| 149 static int nop() { return kNop; } | 149 static int nop() { return kNop; } |
| 150 | 150 |
| 151 // No reservation for large object space necessary. | 151 // No reservation for large object space necessary. |
| 152 static const int kNumberOfPreallocatedSpaces = LO_SPACE; | 152 static const int kNumberOfPreallocatedSpaces = LO_SPACE; |
| 153 static const int kNumberOfSpaces = INVALID_SPACE; | 153 static const int kNumberOfSpaces = INVALID_SPACE; |
| 154 | 154 |
| 155 // To encode object for back-references. | |
| 156 class OffsetBits : public BitField<uint32_t, 0, kPageSizeBits> {}; | |
| 157 class ChunkIndexBits | |
| 158 : public BitField<uint32_t, kPageSizeBits, 32 - kPageSizeBits> {}; | |
| 159 | |
| 160 protected: | 155 protected: |
| 161 // Where the pointed-to object can be found: | 156 // Where the pointed-to object can be found: |
| 162 enum Where { | 157 enum Where { |
| 163 kNewObject = 0, // Object is next in snapshot. | 158 kNewObject = 0, // Object is next in snapshot. |
| 164 // 1-7 One per space. | 159 // 1-7 One per space. |
| 165 kRootArray = 0x9, // Object is found in root array. | 160 kRootArray = 0x9, // Object is found in root array. |
| 166 kPartialSnapshotCache = 0xa, // Object is in the cache. | 161 kPartialSnapshotCache = 0xa, // Object is in the cache. |
| 167 kExternalReference = 0xb, // Pointer to an external reference. | 162 kExternalReference = 0xb, // Pointer to an external reference. |
| 168 kSkip = 0xc, // Skip n bytes. | 163 kSkip = 0xc, // Skip n bytes. |
| 169 kBuiltin = 0xd, // Builtin code object. | 164 kBuiltin = 0xd, // Builtin code object. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 class Deserializer: public SerializerDeserializer { | 241 class Deserializer: public SerializerDeserializer { |
| 247 public: | 242 public: |
| 248 // Create a deserializer from a snapshot byte source. | 243 // Create a deserializer from a snapshot byte source. |
| 249 explicit Deserializer(SnapshotByteSource* source); | 244 explicit Deserializer(SnapshotByteSource* source); |
| 250 | 245 |
| 251 virtual ~Deserializer(); | 246 virtual ~Deserializer(); |
| 252 | 247 |
| 253 // Deserialize the snapshot into an empty heap. | 248 // Deserialize the snapshot into an empty heap. |
| 254 void Deserialize(Isolate* isolate); | 249 void Deserialize(Isolate* isolate); |
| 255 | 250 |
| 256 enum OnOOM { FATAL_ON_OOM, NULL_ON_OOM }; | 251 // Deserialize a single object and the objects reachable from it. |
| 252 void DeserializePartial(Isolate* isolate, Object** root); |
| 257 | 253 |
| 258 // Deserialize a single object and the objects reachable from it. | 254 void set_reservation(int space_number, int reservation) { |
| 259 // We may want to abort gracefully even if deserialization fails. | 255 DCHECK(space_number >= 0); |
| 260 void DeserializePartial(Isolate* isolate, Object** root, | 256 DCHECK(space_number < kNumberOfSpaces); |
| 261 OnOOM on_oom = FATAL_ON_OOM); | 257 reservations_[space_number] = reservation; |
| 262 | |
| 263 void AddReservation(int space, uint32_t chunk) { | |
| 264 DCHECK(space >= 0); | |
| 265 DCHECK(space < kNumberOfSpaces); | |
| 266 DCHECK(space == LO_SPACE || chunk < Page::kMaxRegularHeapObjectSize); | |
| 267 reservations_[space].Add({chunk, NULL, NULL}); | |
| 268 } | 258 } |
| 269 | 259 |
| 270 void FlushICacheForNewCodeObjects(); | 260 void FlushICacheForNewCodeObjects(); |
| 271 | 261 |
| 272 // Serialized user code reference certain objects that are provided in a list | 262 // Serialized user code reference certain objects that are provided in a list |
| 273 // By calling this method, we assume that we are deserializing user code. | 263 // By calling this method, we assume that we are deserializing user code. |
| 274 void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) { | 264 void SetAttachedObjects(Vector<Handle<Object> >* attached_objects) { |
| 275 attached_objects_ = attached_objects; | 265 attached_objects_ = attached_objects; |
| 276 } | 266 } |
| 277 | 267 |
| 278 bool deserializing_user_code() { return attached_objects_ != NULL; } | 268 bool deserializing_user_code() { return attached_objects_ != NULL; } |
| 279 | 269 |
| 280 private: | 270 private: |
| 281 virtual void VisitPointers(Object** start, Object** end); | 271 virtual void VisitPointers(Object** start, Object** end); |
| 282 | 272 |
| 283 virtual void VisitRuntimeEntry(RelocInfo* rinfo) { | 273 virtual void VisitRuntimeEntry(RelocInfo* rinfo) { |
| 284 UNREACHABLE(); | 274 UNREACHABLE(); |
| 285 } | 275 } |
| 286 | 276 |
| 287 bool ReserveSpace(); | |
| 288 | |
| 289 // Allocation sites are present in the snapshot, and must be linked into | 277 // Allocation sites are present in the snapshot, and must be linked into |
| 290 // a list at deserialization time. | 278 // a list at deserialization time. |
| 291 void RelinkAllocationSite(AllocationSite* site); | 279 void RelinkAllocationSite(AllocationSite* site); |
| 292 | 280 |
| 293 // Fills in some heap data in an area from start to end (non-inclusive). The | 281 // Fills in some heap data in an area from start to end (non-inclusive). The |
| 294 // space id is used for the write barrier. The object_address is the address | 282 // space id is used for the write barrier. The object_address is the address |
| 295 // of the object we are writing into, or NULL if we are not writing into an | 283 // of the object we are writing into, or NULL if we are not writing into an |
| 296 // object, i.e. if we are writing a series of tagged values that are not on | 284 // object, i.e. if we are writing a series of tagged values that are not on |
| 297 // the heap. | 285 // the heap. |
| 298 void ReadData(Object** start, Object** end, int space, | 286 void ReadChunk( |
| 299 Address object_address); | 287 Object** start, Object** end, int space, Address object_address); |
| 300 void ReadObject(int space_number, Object** write_back); | 288 void ReadObject(int space_number, Object** write_back); |
| 301 Address Allocate(int space_index, int size); | 289 Address Allocate(int space_index, int size); |
| 302 | 290 |
| 303 // Special handling for serialized code like hooking up internalized strings. | 291 // Special handling for serialized code like hooking up internalized strings. |
| 304 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); | 292 HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); |
| 305 Object* ProcessBackRefInSerializedCode(Object* obj); | 293 Object* ProcessBackRefInSerializedCode(Object* obj); |
| 306 | 294 |
| 307 // This returns the address of an object that has been described in the | 295 // This returns the address of an object that has been described in the |
| 308 // snapshot by chunk index and offset. | 296 // snapshot as being offset bytes back in a particular space. |
| 309 HeapObject* GetBackReferencedObject(int space) { | 297 HeapObject* GetAddressFromEnd(int space) { |
| 310 if (space == LO_SPACE) { | 298 int offset = source_->GetInt(); |
| 311 uint32_t index = source_->GetInt(); | 299 if (space == LO_SPACE) return deserialized_large_objects_[offset]; |
| 312 return deserialized_large_objects_[index]; | 300 DCHECK(space < kNumberOfPreallocatedSpaces); |
| 313 } else { | 301 offset <<= kObjectAlignmentBits; |
| 314 uint32_t allocation = source_->GetInt() << kObjectAlignmentBits; | 302 return HeapObject::FromAddress(high_water_[space] - offset); |
| 315 DCHECK(space < kNumberOfPreallocatedSpaces); | |
| 316 uint32_t chunk_index = ChunkIndexBits::decode(allocation); | |
| 317 uint32_t offset = OffsetBits::decode(allocation); | |
| 318 DCHECK_LE(chunk_index, current_chunk_[space]); | |
| 319 return HeapObject::FromAddress(reservations_[space][chunk_index].start + | |
| 320 offset); | |
| 321 } | |
| 322 } | 303 } |
| 323 | 304 |
| 324 // Cached current isolate. | 305 // Cached current isolate. |
| 325 Isolate* isolate_; | 306 Isolate* isolate_; |
| 326 | 307 |
| 327 // Objects from the attached object descriptions in the serialized user code. | 308 // Objects from the attached object descriptions in the serialized user code. |
| 328 Vector<Handle<Object> >* attached_objects_; | 309 Vector<Handle<Object> >* attached_objects_; |
| 329 | 310 |
| 330 SnapshotByteSource* source_; | 311 SnapshotByteSource* source_; |
| 331 // The address of the next object that will be allocated in each space. | 312 // This is the address of the next object that will be allocated in each |
| 332 // Each space has a number of chunks reserved by the GC, with each chunk | 313 // space. It is used to calculate the addresses of back-references. |
| 333 // fitting into a page. Deserialized objects are allocated into the | |
| 334 // current chunk of the target space by bumping up high water mark. | |
| 335 Heap::Reservation reservations_[kNumberOfSpaces]; | |
| 336 uint32_t current_chunk_[kNumberOfPreallocatedSpaces]; | |
| 337 Address high_water_[kNumberOfPreallocatedSpaces]; | 314 Address high_water_[kNumberOfPreallocatedSpaces]; |
| 338 | 315 |
| 316 int reservations_[kNumberOfSpaces]; |
| 317 static const intptr_t kUninitializedReservation = -1; |
| 318 |
| 339 ExternalReferenceDecoder* external_reference_decoder_; | 319 ExternalReferenceDecoder* external_reference_decoder_; |
| 340 | 320 |
| 341 List<HeapObject*> deserialized_large_objects_; | 321 List<HeapObject*> deserialized_large_objects_; |
| 342 | 322 |
| 343 DISALLOW_COPY_AND_ASSIGN(Deserializer); | 323 DISALLOW_COPY_AND_ASSIGN(Deserializer); |
| 344 }; | 324 }; |
| 345 | 325 |
| 346 | 326 |
| 347 // Mapping objects to their location after deserialization. | 327 // Mapping objects to their location after deserialization. |
| 348 // This is used during building, but not at runtime by V8. | 328 // This is used during building, but not at runtime by V8. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 | 373 |
| 394 | 374 |
| 395 class CodeAddressMap; | 375 class CodeAddressMap; |
| 396 | 376 |
| 397 // There can be only one serializer per V8 process. | 377 // There can be only one serializer per V8 process. |
| 398 class Serializer : public SerializerDeserializer { | 378 class Serializer : public SerializerDeserializer { |
| 399 public: | 379 public: |
| 400 Serializer(Isolate* isolate, SnapshotByteSink* sink); | 380 Serializer(Isolate* isolate, SnapshotByteSink* sink); |
| 401 ~Serializer(); | 381 ~Serializer(); |
| 402 void VisitPointers(Object** start, Object** end); | 382 void VisitPointers(Object** start, Object** end); |
| 403 | 383 // You can call this after serialization to find out how much space was used |
| 404 void FinalizeAllocation(); | 384 // in each space. |
| 405 | 385 int CurrentAllocationAddress(int space) const { |
| 406 Vector<const uint32_t> FinalAllocationChunks(int space) const { | 386 DCHECK(space < kNumberOfSpaces); |
| 407 DCHECK_EQ(1, completed_chunks_[LO_SPACE].length()); // Already finalized. | 387 return fullness_[space]; |
| 408 DCHECK_EQ(0, pending_chunk_[space]); // No pending chunks. | |
| 409 return completed_chunks_[space].ToConstVector(); | |
| 410 } | 388 } |
| 411 | 389 |
| 412 Isolate* isolate() const { return isolate_; } | 390 Isolate* isolate() const { return isolate_; } |
| 413 | 391 |
| 414 SerializationAddressMapper* address_mapper() { return &address_mapper_; } | 392 SerializationAddressMapper* address_mapper() { return &address_mapper_; } |
| 415 void PutRoot(int index, | 393 void PutRoot(int index, |
| 416 HeapObject* object, | 394 HeapObject* object, |
| 417 HowToCode how, | 395 HowToCode how, |
| 418 WhereToPoint where, | 396 WhereToPoint where, |
| 419 int skip); | 397 int skip); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 HowToCode how_to_code, | 463 HowToCode how_to_code, |
| 486 WhereToPoint where_to_point, | 464 WhereToPoint where_to_point, |
| 487 int skip) = 0; | 465 int skip) = 0; |
| 488 void SerializeReferenceToPreviousObject(HeapObject* heap_object, | 466 void SerializeReferenceToPreviousObject(HeapObject* heap_object, |
| 489 HowToCode how_to_code, | 467 HowToCode how_to_code, |
| 490 WhereToPoint where_to_point, | 468 WhereToPoint where_to_point, |
| 491 int skip); | 469 int skip); |
| 492 void InitializeAllocators(); | 470 void InitializeAllocators(); |
| 493 // This will return the space for an object. | 471 // This will return the space for an object. |
| 494 static int SpaceOfObject(HeapObject* object); | 472 static int SpaceOfObject(HeapObject* object); |
| 495 uint32_t AllocateLargeObject(int size); | 473 int AllocateLargeObject(int size); |
| 496 uint32_t Allocate(int space, int size); | 474 int Allocate(int space, int size); |
| 497 int EncodeExternalReference(Address addr) { | 475 int EncodeExternalReference(Address addr) { |
| 498 return external_reference_encoder_->Encode(addr); | 476 return external_reference_encoder_->Encode(addr); |
| 499 } | 477 } |
| 500 | 478 |
| 501 int SpaceAreaSize(int space); | 479 int SpaceAreaSize(int space); |
| 502 | 480 |
| 503 // Some roots should not be serialized, because their actual value depends on | 481 // Some roots should not be serialized, because their actual value depends on |
| 504 // absolute addresses and they are reset after deserialization, anyway. | 482 // absolute addresses and they are reset after deserialization, anyway. |
| 505 bool ShouldBeSkipped(Object** current); | 483 bool ShouldBeSkipped(Object** current); |
| 506 | 484 |
| 507 Isolate* isolate_; | 485 Isolate* isolate_; |
| 508 | 486 // Keep track of the fullness of each space in order to generate |
| 509 // Objects from the same space are put into chunks for bulk-allocation | 487 // relative addresses for back references. |
| 510 // when deserializing. We have to make sure that each chunk fits into a | 488 int fullness_[kNumberOfSpaces]; |
| 511 // page. So we track the chunk size in pending_chunk_ of a space, but | |
| 512 // when it exceeds a page, we complete the current chunk and start a new one. | |
| 513 uint32_t pending_chunk_[kNumberOfSpaces]; | |
| 514 List<uint32_t> completed_chunks_[kNumberOfSpaces]; | |
| 515 | |
| 516 SnapshotByteSink* sink_; | 489 SnapshotByteSink* sink_; |
| 517 ExternalReferenceEncoder* external_reference_encoder_; | 490 ExternalReferenceEncoder* external_reference_encoder_; |
| 518 | 491 |
| 519 SerializationAddressMapper address_mapper_; | 492 SerializationAddressMapper address_mapper_; |
| 520 intptr_t root_index_wave_front_; | 493 intptr_t root_index_wave_front_; |
| 521 void Pad(); | 494 void Pad(); |
| 522 | 495 |
| 523 friend class ObjectSerializer; | 496 friend class ObjectSerializer; |
| 524 friend class Deserializer; | 497 friend class Deserializer; |
| 525 | 498 |
| 526 // We may not need the code address map for logging for every instance | 499 // We may not need the code address map for logging for every instance |
| 527 // of the serializer. Initialize it on demand. | 500 // of the serializer. Initialize it on demand. |
| 528 void InitializeCodeAddressMap(); | 501 void InitializeCodeAddressMap(); |
| 529 | 502 |
| 530 private: | 503 private: |
| 531 CodeAddressMap* code_address_map_; | 504 CodeAddressMap* code_address_map_; |
| 532 // We map serialized large objects to indexes for back-referencing. | 505 // We map serialized large objects to indexes for back-referencing. |
| 533 uint32_t seen_large_objects_index_; | 506 int seen_large_objects_index_; |
| 534 DISALLOW_COPY_AND_ASSIGN(Serializer); | 507 DISALLOW_COPY_AND_ASSIGN(Serializer); |
| 535 }; | 508 }; |
| 536 | 509 |
| 537 | 510 |
| 538 class PartialSerializer : public Serializer { | 511 class PartialSerializer : public Serializer { |
| 539 public: | 512 public: |
| 540 PartialSerializer(Isolate* isolate, | 513 PartialSerializer(Isolate* isolate, |
| 541 Serializer* startup_snapshot_serializer, | 514 Serializer* startup_snapshot_serializer, |
| 542 SnapshotByteSink* sink) | 515 SnapshotByteSink* sink) |
| 543 : Serializer(isolate, sink), | 516 : Serializer(isolate, sink), |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 DISALLOW_COPY_AND_ASSIGN(StartupSerializer); | 578 DISALLOW_COPY_AND_ASSIGN(StartupSerializer); |
| 606 }; | 579 }; |
| 607 | 580 |
| 608 | 581 |
| 609 class CodeSerializer : public Serializer { | 582 class CodeSerializer : public Serializer { |
| 610 public: | 583 public: |
| 611 static ScriptData* Serialize(Isolate* isolate, | 584 static ScriptData* Serialize(Isolate* isolate, |
| 612 Handle<SharedFunctionInfo> info, | 585 Handle<SharedFunctionInfo> info, |
| 613 Handle<String> source); | 586 Handle<String> source); |
| 614 | 587 |
| 615 MUST_USE_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize( | 588 static Handle<SharedFunctionInfo> Deserialize(Isolate* isolate, |
| 616 Isolate* isolate, ScriptData* data, Handle<String> source); | 589 ScriptData* data, |
| 590 Handle<String> source); |
| 617 | 591 |
| 618 static const int kSourceObjectIndex = 0; | 592 static const int kSourceObjectIndex = 0; |
| 619 static const int kCodeStubsBaseIndex = 1; | 593 static const int kCodeStubsBaseIndex = 1; |
| 620 | 594 |
| 621 String* source() { | 595 String* source() { |
| 622 DCHECK(!AllowHeapAllocation::IsAllowed()); | 596 DCHECK(!AllowHeapAllocation::IsAllowed()); |
| 623 return source_; | 597 return source_; |
| 624 } | 598 } |
| 625 | 599 |
| 626 List<uint32_t>* stub_keys() { return &stub_keys_; } | 600 List<uint32_t>* stub_keys() { return &stub_keys_; } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 | 647 |
| 674 // Return ScriptData object and relinquish ownership over it to the caller. | 648 // Return ScriptData object and relinquish ownership over it to the caller. |
| 675 ScriptData* GetScriptData() { | 649 ScriptData* GetScriptData() { |
| 676 ScriptData* result = script_data_; | 650 ScriptData* result = script_data_; |
| 677 script_data_ = NULL; | 651 script_data_ = NULL; |
| 678 DCHECK(owns_script_data_); | 652 DCHECK(owns_script_data_); |
| 679 owns_script_data_ = false; | 653 owns_script_data_ = false; |
| 680 return result; | 654 return result; |
| 681 } | 655 } |
| 682 | 656 |
| 683 class Reservation { | |
| 684 public: | |
| 685 uint32_t chunk_size() const { return ChunkSizeBits::decode(reservation); } | |
| 686 bool is_last_chunk() const { return IsLastChunkBits::decode(reservation); } | |
| 687 | |
| 688 private: | |
| 689 uint32_t reservation; | |
| 690 | |
| 691 DISALLOW_COPY_AND_ASSIGN(Reservation); | |
| 692 }; | |
| 693 | |
| 694 Vector<const Reservation> Reservations() const { | |
| 695 return Vector<const Reservation>(reinterpret_cast<const Reservation*>( | |
| 696 script_data_->data() + kHeaderSize), | |
| 697 GetHeaderValue(kReservationsOffset)); | |
| 698 } | |
| 699 | |
| 700 Vector<const uint32_t> CodeStubKeys() const { | 657 Vector<const uint32_t> CodeStubKeys() const { |
| 701 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; | 658 return Vector<const uint32_t>( |
| 702 const byte* start = script_data_->data() + kHeaderSize + reservations_size; | 659 reinterpret_cast<const uint32_t*>(script_data_->data() + kHeaderSize), |
| 703 return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), | 660 GetHeaderValue(kNumCodeStubKeysOffset)); |
| 704 GetHeaderValue(kNumCodeStubKeysOffset)); | |
| 705 } | 661 } |
| 706 | 662 |
| 707 const byte* Payload() const { | 663 const byte* Payload() const { |
| 708 int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; | |
| 709 int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size; | 664 int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size; |
| 710 return script_data_->data() + kHeaderSize + reservations_size + | 665 return script_data_->data() + kHeaderSize + code_stubs_size; |
| 711 code_stubs_size; | |
| 712 } | 666 } |
| 713 | 667 |
| 714 int PayloadLength() const { | 668 int PayloadLength() const { |
| 715 int payload_length = GetHeaderValue(kPayloadLengthOffset); | 669 int payload_length = GetHeaderValue(kPayloadLengthOffset); |
| 716 DCHECK_EQ(script_data_->data() + script_data_->length(), | 670 DCHECK_EQ(script_data_->data() + script_data_->length(), |
| 717 Payload() + payload_length); | 671 Payload() + payload_length); |
| 718 return payload_length; | 672 return payload_length; |
| 719 } | 673 } |
| 720 | 674 |
| 675 int GetReservation(int space) const { |
| 676 return GetHeaderValue(kReservationsOffset + space); |
| 677 } |
| 678 |
| 721 private: | 679 private: |
| 722 void SetHeaderValue(int offset, int value) { | 680 void SetHeaderValue(int offset, int value) { |
| 723 reinterpret_cast<int*>(const_cast<byte*>(script_data_->data()))[offset] = | 681 reinterpret_cast<int*>(const_cast<byte*>(script_data_->data()))[offset] = |
| 724 value; | 682 value; |
| 725 } | 683 } |
| 726 | 684 |
| 727 int GetHeaderValue(int offset) const { | 685 int GetHeaderValue(int offset) const { |
| 728 return reinterpret_cast<const int*>(script_data_->data())[offset]; | 686 return reinterpret_cast<const int*>(script_data_->data())[offset]; |
| 729 } | 687 } |
| 730 | 688 |
| 731 bool IsSane(String* source); | 689 bool IsSane(String* source); |
| 732 | 690 |
| 733 int CheckSum(String* source); | 691 int CheckSum(String* source); |
| 734 | 692 |
| 735 // The data header consists of int-sized entries: | 693 // The data header consists of int-sized entries: |
| 736 // [0] version hash | 694 // [0] version hash |
| 737 // [1] number of code stub keys | 695 // [1] number of code stub keys |
| 738 // [2] payload length | 696 // [2] payload length |
| 739 // [3..9] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE. | 697 // [3..9] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE. |
| 740 static const int kCheckSumOffset = 0; | 698 static const int kCheckSumOffset = 0; |
| 741 static const int kReservationsOffset = 1; | 699 static const int kNumCodeStubKeysOffset = 1; |
| 742 static const int kNumCodeStubKeysOffset = 2; | 700 static const int kPayloadLengthOffset = 2; |
| 743 static const int kPayloadLengthOffset = 3; | 701 static const int kReservationsOffset = 3; |
| 744 static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize; | |
| 745 | 702 |
| 746 class ChunkSizeBits : public BitField<uint32_t, 0, 31> {}; | 703 static const int kHeaderEntries = |
| 747 class IsLastChunkBits : public BitField<bool, 31, 1> {}; | 704 kReservationsOffset + SerializerDeserializer::kNumberOfSpaces; |
| 705 static const int kHeaderSize = kHeaderEntries * kIntSize; |
| 748 | 706 |
| 749 // Following the header, we store, in sequential order | 707 // Following the header, we store, in sequential order |
| 750 // - code stub keys | 708 // - code stub keys |
| 751 // - serialization payload | 709 // - serialization payload |
| 752 | 710 |
| 753 ScriptData* script_data_; | 711 ScriptData* script_data_; |
| 754 bool owns_script_data_; | 712 bool owns_script_data_; |
| 755 }; | 713 }; |
| 756 } } // namespace v8::internal | 714 } } // namespace v8::internal |
| 757 | 715 |
| 758 #endif // V8_SERIALIZE_H_ | 716 #endif // V8_SERIALIZE_H_ |
| OLD | NEW |