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 |