Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Unified Diff: src/serialize.h

Issue 653033002: Break deserializer reservations into chunks that fit onto a page. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments and rebase Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/mksnapshot.cc ('k') | src/serialize.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/serialize.h
diff --git a/src/serialize.h b/src/serialize.h
index 6fa7a341e7a2de1589a9e886f56caec03a6efd65..6e1f6512350b24dc56e39b1b25d38ce5b8095652 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -152,6 +152,11 @@ class SerializerDeserializer: public ObjectVisitor {
static const int kNumberOfPreallocatedSpaces = LO_SPACE;
static const int kNumberOfSpaces = INVALID_SPACE;
+ // To encode object for back-references.
+ class OffsetBits : public BitField<uint32_t, 0, kPageSizeBits> {};
+ class ChunkIndexBits
+ : public BitField<uint32_t, kPageSizeBits, 32 - kPageSizeBits> {};
+
protected:
// Where the pointed-to object can be found:
enum Where {
@@ -248,13 +253,18 @@ class Deserializer: public SerializerDeserializer {
// Deserialize the snapshot into an empty heap.
void Deserialize(Isolate* isolate);
+ enum OnOOM { FATAL_ON_OOM, NULL_ON_OOM };
+
// Deserialize a single object and the objects reachable from it.
- void DeserializePartial(Isolate* isolate, Object** root);
+ // We may want to abort gracefully even if deserialization fails.
+ void DeserializePartial(Isolate* isolate, Object** root,
+ OnOOM on_oom = FATAL_ON_OOM);
- void set_reservation(int space_number, int reservation) {
- DCHECK(space_number >= 0);
- DCHECK(space_number < kNumberOfSpaces);
- reservations_[space_number] = reservation;
+ void AddReservation(int space, uint32_t chunk) {
+ DCHECK(space >= 0);
+ DCHECK(space < kNumberOfSpaces);
+ DCHECK(space == LO_SPACE || chunk < Page::kMaxRegularHeapObjectSize);
+ reservations_[space].Add({chunk, NULL, NULL});
}
void FlushICacheForNewCodeObjects();
@@ -274,6 +284,8 @@ class Deserializer: public SerializerDeserializer {
UNREACHABLE();
}
+ bool ReserveSpace();
+
// Allocation sites are present in the snapshot, and must be linked into
// a list at deserialization time.
void RelinkAllocationSite(AllocationSite* site);
@@ -283,8 +295,8 @@ class Deserializer: public SerializerDeserializer {
// of the object we are writing into, or NULL if we are not writing into an
// object, i.e. if we are writing a series of tagged values that are not on
// the heap.
- void ReadChunk(
- Object** start, Object** end, int space, Address object_address);
+ void ReadData(Object** start, Object** end, int space,
+ Address object_address);
void ReadObject(int space_number, Object** write_back);
Address Allocate(int space_index, int size);
@@ -293,13 +305,20 @@ class Deserializer: public SerializerDeserializer {
Object* ProcessBackRefInSerializedCode(Object* obj);
// This returns the address of an object that has been described in the
- // snapshot as being offset bytes back in a particular space.
- HeapObject* GetAddressFromEnd(int space) {
- int offset = source_->GetInt();
- if (space == LO_SPACE) return deserialized_large_objects_[offset];
- DCHECK(space < kNumberOfPreallocatedSpaces);
- offset <<= kObjectAlignmentBits;
- return HeapObject::FromAddress(high_water_[space] - offset);
+ // snapshot by chunk index and offset.
+ HeapObject* GetBackReferencedObject(int space) {
+ if (space == LO_SPACE) {
+ uint32_t index = source_->GetInt();
+ return deserialized_large_objects_[index];
+ } else {
+ uint32_t allocation = source_->GetInt() << kObjectAlignmentBits;
+ DCHECK(space < kNumberOfPreallocatedSpaces);
+ uint32_t chunk_index = ChunkIndexBits::decode(allocation);
+ uint32_t offset = OffsetBits::decode(allocation);
+ DCHECK_LE(chunk_index, current_chunk_[space]);
+ return HeapObject::FromAddress(reservations_[space][chunk_index].start +
+ offset);
+ }
}
// Cached current isolate.
@@ -309,13 +328,14 @@ class Deserializer: public SerializerDeserializer {
Vector<Handle<Object> >* attached_objects_;
SnapshotByteSource* source_;
- // This is the address of the next object that will be allocated in each
- // space. It is used to calculate the addresses of back-references.
+ // 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
+ // current chunk of the target space by bumping up high water mark.
+ Heap::Reservation reservations_[kNumberOfSpaces];
+ uint32_t current_chunk_[kNumberOfPreallocatedSpaces];
Address high_water_[kNumberOfPreallocatedSpaces];
- int reservations_[kNumberOfSpaces];
- static const intptr_t kUninitializedReservation = -1;
-
ExternalReferenceDecoder* external_reference_decoder_;
List<HeapObject*> deserialized_large_objects_;
@@ -380,11 +400,13 @@ class Serializer : public SerializerDeserializer {
Serializer(Isolate* isolate, SnapshotByteSink* sink);
~Serializer();
void VisitPointers(Object** start, Object** end);
- // You can call this after serialization to find out how much space was used
- // in each space.
- int CurrentAllocationAddress(int space) const {
- DCHECK(space < kNumberOfSpaces);
- return fullness_[space];
+
+ void FinalizeAllocation();
+
+ Vector<const uint32_t> FinalAllocationChunks(int space) const {
+ DCHECK_EQ(1, completed_chunks_[LO_SPACE].length()); // Already finalized.
+ DCHECK_EQ(0, pending_chunk_[space]); // No pending chunks.
+ return completed_chunks_[space].ToConstVector();
}
Isolate* isolate() const { return isolate_; }
@@ -470,8 +492,8 @@ class Serializer : public SerializerDeserializer {
void InitializeAllocators();
// This will return the space for an object.
static int SpaceOfObject(HeapObject* object);
- int AllocateLargeObject(int size);
- int Allocate(int space, int size);
+ uint32_t AllocateLargeObject(int size);
+ uint32_t Allocate(int space, int size);
int EncodeExternalReference(Address addr) {
return external_reference_encoder_->Encode(addr);
}
@@ -483,9 +505,14 @@ class Serializer : public SerializerDeserializer {
bool ShouldBeSkipped(Object** current);
Isolate* isolate_;
- // Keep track of the fullness of each space in order to generate
- // relative addresses for back references.
- int fullness_[kNumberOfSpaces];
+
+ // Objects from the same space are put into chunks for bulk-allocation
+ // when deserializing. We have to make sure that each chunk fits into a
+ // page. So we track the chunk size in pending_chunk_ of a space, but
+ // when it exceeds a page, we complete the current chunk and start a new one.
+ uint32_t pending_chunk_[kNumberOfSpaces];
+ List<uint32_t> completed_chunks_[kNumberOfSpaces];
+
SnapshotByteSink* sink_;
ExternalReferenceEncoder* external_reference_encoder_;
@@ -503,7 +530,7 @@ class Serializer : public SerializerDeserializer {
private:
CodeAddressMap* code_address_map_;
// We map serialized large objects to indexes for back-referencing.
- int seen_large_objects_index_;
+ uint32_t seen_large_objects_index_;
DISALLOW_COPY_AND_ASSIGN(Serializer);
};
@@ -585,9 +612,8 @@ class CodeSerializer : public Serializer {
Handle<SharedFunctionInfo> info,
Handle<String> source);
- static Handle<SharedFunctionInfo> Deserialize(Isolate* isolate,
- ScriptData* data,
- Handle<String> source);
+ MUST_USE_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize(
+ Isolate* isolate, ScriptData* data, Handle<String> source);
static const int kSourceObjectIndex = 0;
static const int kCodeStubsBaseIndex = 1;
@@ -654,15 +680,35 @@ class SerializedCodeData {
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);
+ };
+
+ 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 {
- return Vector<const uint32_t>(
- reinterpret_cast<const uint32_t*>(script_data_->data() + kHeaderSize),
- GetHeaderValue(kNumCodeStubKeysOffset));
+ 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 + code_stubs_size;
+ return script_data_->data() + kHeaderSize + reservations_size +
+ code_stubs_size;
}
int PayloadLength() const {
@@ -672,10 +718,6 @@ class SerializedCodeData {
return payload_length;
}
- int GetReservation(int space) const {
- return GetHeaderValue(kReservationsOffset + space);
- }
-
private:
void SetHeaderValue(int offset, int value) {
reinterpret_cast<int*>(const_cast<byte*>(script_data_->data()))[offset] =
@@ -696,13 +738,13 @@ class SerializedCodeData {
// [2] payload length
// [3..9] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE.
static const int kCheckSumOffset = 0;
- static const int kNumCodeStubKeysOffset = 1;
- static const int kPayloadLengthOffset = 2;
- static const int kReservationsOffset = 3;
+ static const int kReservationsOffset = 1;
+ static const int kNumCodeStubKeysOffset = 2;
+ static const int kPayloadLengthOffset = 3;
+ static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize;
- static const int kHeaderEntries =
- kReservationsOffset + SerializerDeserializer::kNumberOfSpaces;
- static const int kHeaderSize = kHeaderEntries * 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
« no previous file with comments | « src/mksnapshot.cc ('k') | src/serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698