Chromium Code Reviews| Index: src/serialize.h |
| diff --git a/src/serialize.h b/src/serialize.h |
| index f8e7c9b61ae8aab8d9e42f91973347eb030c8cab..7a6a04cc64b1785b644db39efdcbbd6b4ae99d9e 100644 |
| --- a/src/serialize.h |
| +++ b/src/serialize.h |
| @@ -390,11 +390,56 @@ class SerializerDeserializer: public ObjectVisitor { |
| }; |
| +class SerializedData { |
| + public: |
| + class Reservation { |
| + public: |
| + explicit Reservation(uint32_t size) |
| + : reservation_(ChunkSizeBits::encode(size)) {} |
| + |
| + uint32_t chunk_size() const { return ChunkSizeBits::decode(reservation_); } |
| + bool is_last() const { return IsLastChunkBits::decode(reservation_); } |
| + |
| + void mark_as_last() { reservation_ |= IsLastChunkBits::encode(true); } |
| + |
| + private: |
| + uint32_t reservation_; |
| + }; |
| + |
| + SerializedData(byte* data, int size) |
| + : data_(data), size_(size), owns_data_(false) {} |
| + SerializedData() : data_(NULL), size_(0), owns_data_(true) {} |
|
vogelheim
2014/12/03 18:49:25
Here, owns_data_ == (data_ == NULL), which doesn't
Yang
2014/12/04 08:51:43
Acknowledged.
|
| + |
| + virtual ~SerializedData() { |
| + if (owns_data_) DeleteArray<byte>(data_); |
| + } |
| + |
| + virtual Vector<const Reservation> Reservations() const = 0; |
| + virtual Vector<const byte> Payload() const = 0; |
| + |
| + class ChunkSizeBits : public BitField<uint32_t, 0, 31> {}; |
| + class IsLastChunkBits : public BitField<bool, 31, 1> {}; |
| + |
| + protected: |
| + void SetHeaderValue(int offset, int value) { |
| + reinterpret_cast<int*>(data_)[offset] = value; |
| + } |
| + |
| + int GetHeaderValue(int offset) const { |
| + return reinterpret_cast<const int*>(data_)[offset]; |
| + } |
| + |
| + byte* data_; |
| + int size_; |
| + bool owns_data_; |
| +}; |
| + |
| + |
| // A Deserializer reads a snapshot and reconstructs the Object graph it defines. |
| class Deserializer: public SerializerDeserializer { |
| public: |
| // Create a deserializer from a snapshot byte source. |
| - explicit Deserializer(SnapshotByteSource* source); |
| + explicit Deserializer(SerializedData* serialized_data); |
| virtual ~Deserializer(); |
| @@ -408,12 +453,6 @@ class Deserializer: public SerializerDeserializer { |
| void DeserializePartial(Isolate* isolate, Object** root, |
| OnOOM on_oom = FATAL_ON_OOM); |
| - void AddReservation(int space, uint32_t chunk) { |
| - DCHECK(space >= 0); |
| - DCHECK(space < kNumberOfSpaces); |
| - reservations_[space].Add({chunk, NULL, NULL}); |
| - } |
| - |
| void FlushICacheForNewCodeObjects(); |
| // Serialized user code reference certain objects that are provided in a list |
| @@ -455,10 +494,10 @@ class Deserializer: public SerializerDeserializer { |
| // snapshot by chunk index and offset. |
| HeapObject* GetBackReferencedObject(int space) { |
| if (space == LO_SPACE) { |
| - uint32_t index = source_->GetInt(); |
| + uint32_t index = source_.GetInt(); |
| return deserialized_large_objects_[index]; |
| } else { |
| - BackReference back_reference(source_->GetInt()); |
| + BackReference back_reference(source_.GetInt()); |
| DCHECK(space < kNumberOfPreallocatedSpaces); |
| uint32_t chunk_index = back_reference.chunk_index(); |
| DCHECK_LE(chunk_index, current_chunk_[space]); |
| @@ -474,7 +513,7 @@ class Deserializer: public SerializerDeserializer { |
| // Objects from the attached object descriptions in the serialized user code. |
| Vector<Handle<Object> >* attached_objects_; |
| - SnapshotByteSource* source_; |
| + SnapshotByteSource source_; |
| // The address of the next object that will be allocated in each space. |
| // Each space has a number of chunks reserved by the GC, with each chunk |
| // fitting into a page. Deserialized objects are allocated into the |
| @@ -500,16 +539,7 @@ class Serializer : public SerializerDeserializer { |
| ~Serializer(); |
| virtual void VisitPointers(Object** start, Object** end) OVERRIDE; |
| - void FinalizeAllocation(); |
| - |
| - Vector<const uint32_t> FinalAllocationChunks(int space) const { |
| - if (space == LO_SPACE) { |
| - return Vector<const uint32_t>(&large_objects_total_size_, 1); |
| - } else { |
| - DCHECK_EQ(0, pending_chunk_[space]); // No pending chunks. |
| - return completed_chunks_[space].ToConstVector(); |
| - } |
| - } |
| + void EncodeReservations(List<SerializedData::Reservation>* out) const; |
| Isolate* isolate() const { return isolate_; } |
| @@ -723,7 +753,7 @@ class CodeSerializer : public Serializer { |
| return source_; |
| } |
| - List<uint32_t>* stub_keys() { return &stub_keys_; } |
| + const List<uint32_t>* stub_keys() const { return &stub_keys_; } |
| int num_internalized_strings() const { return num_internalized_strings_; } |
| private: |
| @@ -760,10 +790,42 @@ class CodeSerializer : public Serializer { |
| }; |
| +// Wrapper around reservation sizes and the serialization payload. |
| +class SnapshotData : public SerializedData { |
| + public: |
| + // Used when producing. |
| + SnapshotData(const SnapshotByteSink& sink, const Serializer& ser); |
| + |
| + // Used when consuming. |
| + explicit SnapshotData(const byte* data, int size) |
| + : SerializedData(const_cast<byte*>(data), size) { |
| + CHECK(IsSane()); |
| + } |
| + |
| + virtual Vector<const Reservation> Reservations() const OVERRIDE; |
| + virtual Vector<const byte> Payload() const OVERRIDE; |
| + |
| + Vector<const byte> RawData() const { |
| + return Vector<const byte>(data_, size_); |
| + } |
| + |
| + private: |
| + bool IsSane(); |
| + // The data header consists of int-sized entries: |
| + // [0] version hash |
| + // [1] number of reservation size entries |
| + // [2] payload length |
| + static const int kCheckSumOffset = 0; |
| + static const int kReservationsOffset = 1; |
| + static const int kPayloadLengthOffset = 2; |
| + static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize; |
| +}; |
| + |
| + |
| // Wrapper around ScriptData to provide code-serializer-specific functionality. |
| -class SerializedCodeData { |
| +class SerializedCodeData : public SerializedData { |
| public: |
| - // Used by when consuming. |
| + // Used when consuming. |
| static SerializedCodeData* FromCachedData(ScriptData* cached_data, |
| String* source) { |
| DisallowHeapAllocation no_gc; |
| @@ -775,73 +837,20 @@ class SerializedCodeData { |
| } |
| // Used when producing. |
| - SerializedCodeData(const List<byte>& payload, CodeSerializer* cs); |
| - |
| - ~SerializedCodeData() { |
| - if (owns_script_data_) DeleteArray<byte>(data_); |
| - } |
| + SerializedCodeData(const List<byte>& payload, const CodeSerializer& cs); |
| // Return ScriptData object and relinquish ownership over it to the caller. |
| - ScriptData* GetScriptData() { |
| - DCHECK(owns_script_data_); |
| - ScriptData* result = new ScriptData(data_, size_); |
| - result->AcquireDataOwnership(); |
| - return result; |
| - } |
| - |
| - class Reservation { |
| - public: |
| - uint32_t chunk_size() const { return ChunkSizeBits::decode(reservation); } |
| - bool is_last_chunk() const { return IsLastChunkBits::decode(reservation); } |
| - |
| - private: |
| - uint32_t reservation; |
| - |
| - DISALLOW_COPY_AND_ASSIGN(Reservation); |
| - }; |
| - |
| - int NumInternalizedStrings() const { |
| - return GetHeaderValue(kNumInternalizedStringsOffset); |
| - } |
| - |
| - Vector<const Reservation> Reservations() const { |
| - return Vector<const Reservation>( |
| - reinterpret_cast<const Reservation*>(data_ + kHeaderSize), |
| - GetHeaderValue(kReservationsOffset)); |
| - } |
| + ScriptData* GetScriptData(); |
| - Vector<const uint32_t> CodeStubKeys() const { |
| - int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; |
| - const byte* start = data_ + kHeaderSize + reservations_size; |
| - return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), |
| - GetHeaderValue(kNumCodeStubKeysOffset)); |
| - } |
| + virtual Vector<const Reservation> Reservations() const OVERRIDE; |
| + virtual Vector<const byte> Payload() const OVERRIDE; |
| - const byte* Payload() const { |
| - int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; |
| - int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size; |
| - return data_ + kHeaderSize + reservations_size + code_stubs_size; |
| - } |
| - |
| - int PayloadLength() const { |
| - int payload_length = GetHeaderValue(kPayloadLengthOffset); |
| - DCHECK_EQ(data_ + size_, Payload() + payload_length); |
| - return payload_length; |
| - } |
| + int NumInternalizedStrings() const; |
| + Vector<const uint32_t> CodeStubKeys() const; |
| private: |
| explicit SerializedCodeData(ScriptData* data) |
| - : data_(const_cast<byte*>(data->data())), |
| - size_(data->length()), |
| - owns_script_data_(false) {} |
| - |
| - void SetHeaderValue(int offset, int value) { |
| - reinterpret_cast<int*>(data_)[offset] = value; |
| - } |
| - |
| - int GetHeaderValue(int offset) const { |
| - return reinterpret_cast<const int*>(data_)[offset]; |
| - } |
| + : SerializedData(const_cast<byte*>(data->data()), data->length()) {} |
| bool IsSane(String* source); |
| @@ -852,20 +861,13 @@ class SerializedCodeData { |
| // [1] number of internalized strings |
| // [2] number of code stub keys |
| // [3] number of reservation size entries |
| - // [3] payload length |
| + // [4] payload length |
| static const int kCheckSumOffset = 0; |
| static const int kNumInternalizedStringsOffset = 1; |
| static const int kReservationsOffset = 2; |
| static const int kNumCodeStubKeysOffset = 3; |
| static const int kPayloadLengthOffset = 4; |
| static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize; |
| - |
| - class ChunkSizeBits : public BitField<uint32_t, 0, 31> {}; |
| - class IsLastChunkBits : public BitField<bool, 31, 1> {}; |
| - |
| - byte* data_; |
| - int size_; |
| - bool owns_script_data_; |
| }; |
| } } // namespace v8::internal |