Index: src/serialize.h |
diff --git a/src/serialize.h b/src/serialize.h |
index 0c3465033388d00f84efe9b1022235751c4aaa0e..43a01e45ac1726e8b50f69d4f9597927759a17ae 100644 |
--- a/src/serialize.h |
+++ b/src/serialize.h |
@@ -453,63 +453,11 @@ |
}; |
-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_(false) {} |
- |
- ~SerializedData() { |
- if (owns_data_) DeleteArray<byte>(data_); |
- } |
- |
- 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]; |
- } |
- |
- void AllocateData(int size); |
- |
- 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. |
- template <class Data> |
- explicit Deserializer(Data* data) |
- : isolate_(NULL), |
- attached_objects_(NULL), |
- source_(data->Payload()), |
- external_reference_decoder_(NULL), |
- deserialized_large_objects_(0) { |
- DecodeReservation(data->Reservations()); |
- } |
+ explicit Deserializer(SnapshotByteSource* source); |
virtual ~Deserializer(); |
@@ -523,6 +471,12 @@ |
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 |
@@ -539,8 +493,6 @@ |
virtual void VisitRuntimeEntry(RelocInfo* rinfo) { |
UNREACHABLE(); |
} |
- |
- void DecodeReservation(Vector<const SerializedData::Reservation> res); |
bool ReserveSpace(); |
@@ -571,7 +523,7 @@ |
// 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 |
@@ -597,7 +549,16 @@ |
~Serializer(); |
virtual void VisitPointers(Object** start, Object** end) OVERRIDE; |
- void EncodeReservations(List<SerializedData::Reservation>* out) const; |
+ 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(); |
+ } |
+ } |
Isolate* isolate() const { return isolate_; } |
@@ -821,7 +782,7 @@ |
return source_; |
} |
- const List<uint32_t>* stub_keys() const { return &stub_keys_; } |
+ List<uint32_t>* stub_keys() { return &stub_keys_; } |
int num_internalized_strings() const { return num_internalized_strings_; } |
private: |
@@ -858,42 +819,10 @@ |
}; |
-// 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()); |
- } |
- |
- Vector<const Reservation> Reservations() const; |
- Vector<const byte> Payload() const; |
- |
- 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 : public SerializedData { |
- public: |
- // Used when consuming. |
+class SerializedCodeData { |
+ public: |
+ // Used by when consuming. |
static SerializedCodeData* FromCachedData(ScriptData* cached_data, |
String* source) { |
DisallowHeapAllocation no_gc; |
@@ -905,20 +834,75 @@ |
} |
// Used when producing. |
- SerializedCodeData(const List<byte>& payload, const CodeSerializer& cs); |
+ SerializedCodeData(const List<byte>& payload, CodeSerializer* cs); |
+ |
+ ~SerializedCodeData() { |
+ if (owns_script_data_) delete script_data_; |
+ } |
// Return ScriptData object and relinquish ownership over it to the caller. |
- ScriptData* GetScriptData(); |
- |
- Vector<const Reservation> Reservations() const; |
- Vector<const byte> Payload() const; |
- |
- int NumInternalizedStrings() const; |
- Vector<const uint32_t> CodeStubKeys() const; |
+ ScriptData* GetScriptData() { |
+ ScriptData* result = script_data_; |
+ script_data_ = NULL; |
+ DCHECK(owns_script_data_); |
+ owns_script_data_ = false; |
+ 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*>( |
+ script_data_->data() + kHeaderSize), |
+ GetHeaderValue(kReservationsOffset)); |
+ } |
+ |
+ Vector<const uint32_t> CodeStubKeys() const { |
+ int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; |
+ const byte* start = script_data_->data() + kHeaderSize + reservations_size; |
+ return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start), |
+ GetHeaderValue(kNumCodeStubKeysOffset)); |
+ } |
+ |
+ const byte* Payload() const { |
+ int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size; |
+ int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size; |
+ return script_data_->data() + kHeaderSize + reservations_size + |
+ code_stubs_size; |
+ } |
+ |
+ int PayloadLength() const { |
+ int payload_length = GetHeaderValue(kPayloadLengthOffset); |
+ DCHECK_EQ(script_data_->data() + script_data_->length(), |
+ Payload() + payload_length); |
+ return payload_length; |
+ } |
private: |
explicit SerializedCodeData(ScriptData* data) |
- : SerializedData(const_cast<byte*>(data->data()), data->length()) {} |
+ : script_data_(data), owns_script_data_(false) {} |
+ |
+ void SetHeaderValue(int offset, int value) { |
+ reinterpret_cast<int*>(const_cast<byte*>(script_data_->data()))[offset] = |
+ value; |
+ } |
+ |
+ int GetHeaderValue(int offset) const { |
+ return reinterpret_cast<const int*>(script_data_->data())[offset]; |
+ } |
bool IsSane(String* source); |
@@ -928,14 +912,24 @@ |
// [0] version hash |
// [1] number of internalized strings |
// [2] number of code stub keys |
- // [3] number of reservation size entries |
- // [4] payload length |
+ // [3] payload length |
+ // [4..10] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE. |
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> {}; |
+ |
+ // Following the header, we store, in sequential order |
+ // - code stub keys |
+ // - serialization payload |
+ |
+ ScriptData* script_data_; |
+ bool owns_script_data_; |
}; |
} } // namespace v8::internal |