Index: src/serialize.h |
diff --git a/src/serialize.h b/src/serialize.h |
index 71b274b330e20f535fa2a3bd93389337fdbf2251..76eb34e3d26e07aa4a87a85ea0489a1bfae53bf0 100644 |
--- a/src/serialize.h |
+++ b/src/serialize.h |
@@ -148,11 +148,15 @@ class SerializerDeserializer: public ObjectVisitor { |
static int nop() { return kNop; } |
+ // No reservation for large object space necessary. |
+ static const int kNumberOfReservedSpaces = LO_SPACE; |
+ static const int kNumberOfSpaces = INVALID_SPACE; |
+ |
protected: |
// Where the pointed-to object can be found: |
enum Where { |
kNewObject = 0, // Object is next in snapshot. |
- // 1-6 One per space. |
+ // 1-7 One per space. |
kRootArray = 0x9, // Object is found in root array. |
kPartialSnapshotCache = 0xa, // Object is in the cache. |
kExternalReference = 0xb, // Pointer to an external reference. |
@@ -161,9 +165,9 @@ class SerializerDeserializer: public ObjectVisitor { |
kAttachedReference = 0xe, // Object is described in an attached list. |
kNop = 0xf, // Does nothing, used to pad. |
kBackref = 0x10, // Object is described relative to end. |
- // 0x11-0x16 One per space. |
+ // 0x11-0x17 One per space. |
kBackrefWithSkip = 0x18, // Object is described relative to end. |
- // 0x19-0x1e One per space. |
+ // 0x19-0x1f One per space. |
// 0x20-0x3f Used by misc. tags below. |
kPointedToMask = 0x3f |
}; |
@@ -225,11 +229,11 @@ class SerializerDeserializer: public ObjectVisitor { |
return byte_code & 0x1f; |
} |
- static const int kNumberOfSpaces = LO_SPACE; |
static const int kAnyOldSpace = -1; |
// A bitmask for getting the space out of an instruction. |
static const int kSpaceMask = 7; |
+ STATIC_ASSERT(kNumberOfSpaces <= kSpaceMask + 1); |
}; |
@@ -249,10 +253,14 @@ class Deserializer: public SerializerDeserializer { |
void set_reservation(int space_number, int reservation) { |
DCHECK(space_number >= 0); |
- DCHECK(space_number <= LAST_SPACE); |
+ DCHECK(space_number < kNumberOfReservedSpaces); |
reservations_[space_number] = reservation; |
} |
+ void set_large_objects_total_size(int size) { |
+ large_objects_total_size_ = size; |
+ } |
+ |
void FlushICacheForNewCodeObjects(); |
// Serialized user code reference certain objects that are provided in a list |
@@ -287,19 +295,33 @@ class Deserializer: public SerializerDeserializer { |
HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj); |
Object* ProcessBackRefInSerializedCode(Object* obj); |
- // This routine both allocates a new object, and also keeps |
- // track of where objects have been allocated so that we can |
- // fix back references when deserializing. |
+ // We know the space requirements before deserialization and can |
+ // pre-allocate that reserved space. During deserialization, all we need |
+ // to do is to bump up the pointer for each space in the reserved |
+ // space. This is also used for fixing back references. |
+ // Since multiple large objects cannot be folded into one large object |
+ // space allocation, we have to do an actual allocation when deserializing |
+ // each allocation. Instead of tracking offset for back references, we |
+ // reference large objects by index. |
Address Allocate(int space_index, int size) { |
- Address address = high_water_[space_index]; |
- high_water_[space_index] = address + size; |
- return address; |
+ if (space_index == LO_SPACE) { |
+ Executability exec = static_cast<Executability>(source_->GetInt()); |
+ HeapObject* obj = isolate_->heap()->ForceAllocateLargeObject(size, exec); |
+ deserialized_large_objects_.Add(obj); |
+ return obj->address(); |
+ } else { |
+ DCHECK(space_index < kNumberOfReservedSpaces); |
+ Address address = high_water_[space_index]; |
+ high_water_[space_index] = address + size; |
+ return address; |
+ } |
} |
// 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]; |
offset <<= kObjectAlignmentBits; |
return HeapObject::FromAddress(high_water_[space] - offset); |
} |
@@ -313,13 +335,16 @@ class Deserializer: public SerializerDeserializer { |
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. |
- Address high_water_[LAST_SPACE + 1]; |
+ Address high_water_[kNumberOfReservedSpaces]; |
- int reservations_[LAST_SPACE + 1]; |
+ int reservations_[kNumberOfReservedSpaces]; |
static const intptr_t kUninitializedReservation = -1; |
ExternalReferenceDecoder* external_reference_decoder_; |
+ List<HeapObject*> deserialized_large_objects_; |
+ int large_objects_total_size_; |
+ |
DISALLOW_COPY_AND_ASSIGN(Deserializer); |
}; |
@@ -383,7 +408,8 @@ class Serializer : public SerializerDeserializer { |
// 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); |
+ if (space == LO_SPACE) return 0; |
+ DCHECK(space < kNumberOfReservedSpaces); |
return fullness_[space]; |
} |
@@ -396,6 +422,8 @@ class Serializer : public SerializerDeserializer { |
WhereToPoint where, |
int skip); |
+ int large_objects_total_size() const { return large_objects_total_size_; } |
+ |
protected: |
static const int kInvalidRootIndex = -1; |
@@ -466,6 +494,7 @@ 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); |
int EncodeExternalReference(Address addr) { |
return external_reference_encoder_->Encode(addr); |
@@ -480,7 +509,7 @@ class Serializer : public SerializerDeserializer { |
Isolate* isolate_; |
// Keep track of the fullness of each space in order to generate |
// relative addresses for back references. |
- int fullness_[LAST_SPACE + 1]; |
+ int fullness_[kNumberOfReservedSpaces]; |
SnapshotByteSink* sink_; |
ExternalReferenceEncoder* external_reference_encoder_; |
@@ -497,6 +526,8 @@ class Serializer : public SerializerDeserializer { |
private: |
CodeAddressMap* code_address_map_; |
+ int seen_large_objects_index_; |
mvstanton
2014/09/22 14:32:14
A comment on the meaning of seen_large_objects_ind
|
+ int large_objects_total_size_; |
DISALLOW_COPY_AND_ASSIGN(Serializer); |
}; |
@@ -667,6 +698,10 @@ class SerializedCodeData { |
return GetHeaderValue(kReservationsOffset + space); |
} |
+ int GetLargeObjectsTotalSize() const { |
+ return GetHeaderValue(kLargeObjectsTotalSizeOffset); |
+ } |
+ |
private: |
void SetHeaderValue(int offset, int value) { |
reinterpret_cast<int*>(const_cast<byte*>(script_data_->data()))[offset] = |
@@ -689,10 +724,11 @@ class SerializedCodeData { |
static const int kCheckSumOffset = 0; |
static const int kNumCodeStubKeysOffset = 1; |
static const int kPayloadLengthOffset = 2; |
- static const int kReservationsOffset = 3; |
+ static const int kLargeObjectsTotalSizeOffset = 3; |
+ static const int kReservationsOffset = 4; |
- static const int kNumSpaces = PROPERTY_CELL_SPACE - NEW_SPACE + 1; |
- static const int kHeaderEntries = kReservationsOffset + kNumSpaces; |
+ static const int kHeaderEntries = |
+ kReservationsOffset + SerializerDeserializer::kNumberOfReservedSpaces; |
static const int kHeaderSize = kHeaderEntries * kIntSize; |
// Following the header, we store, in sequential order |