Index: src/serialize.cc |
diff --git a/src/serialize.cc b/src/serialize.cc |
index dce62fe6db57622cc6b08e9bbf3d2f30ed7af0e2..2b0815e2cc4664fa8a067b6a3df8695d8eadef5f 100644 |
--- a/src/serialize.cc |
+++ b/src/serialize.cc |
@@ -596,8 +596,10 @@ Deserializer::Deserializer(SnapshotByteSource* source) |
: isolate_(NULL), |
attached_objects_(NULL), |
source_(source), |
- external_reference_decoder_(NULL) { |
- for (int i = 0; i < LAST_SPACE + 1; i++) { |
+ external_reference_decoder_(NULL), |
+ deserialized_large_objects_(0), |
+ large_objects_total_size_(0) { |
+ for (int i = 0; i < kNumberOfReservedSpaces; i++) { |
reservations_[i] = kUninitializedReservation; |
} |
} |
@@ -659,10 +661,12 @@ void Deserializer::Deserialize(Isolate* isolate) { |
void Deserializer::DeserializePartial(Isolate* isolate, Object** root) { |
isolate_ = isolate; |
- for (int i = NEW_SPACE; i < kNumberOfSpaces; i++) { |
+ for (int i = NEW_SPACE; i < kNumberOfReservedSpaces; i++) { |
DCHECK(reservations_[i] != kUninitializedReservation); |
} |
- isolate_->heap()->ReserveSpace(reservations_, &high_water_[0]); |
+ Heap* heap = isolate->heap(); |
+ heap->lo_space()->PrepareForDeserialization(large_objects_total_size_); |
+ heap->ReserveSpace(reservations_, &high_water_[0]); |
if (external_reference_decoder_ == NULL) { |
external_reference_decoder_ = new ExternalReferenceDecoder(isolate); |
} |
@@ -798,8 +802,11 @@ void Deserializer::ReadObject(int space_number, |
*write_back = obj; |
#ifdef DEBUG |
- bool is_codespace = (space_number == CODE_SPACE); |
- DCHECK(obj->IsCode() == is_codespace); |
+ if (obj->IsCode()) { |
+ DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE); |
+ } else { |
+ DCHECK(space_number != CODE_SPACE); |
+ } |
#endif |
} |
@@ -925,15 +932,16 @@ void Deserializer::ReadChunk(Object** current, |
// This generates a case and a body for the new space (which has to do extra |
// write barrier handling) and handles the other spaces with 8 fall-through |
// cases and one body. |
-#define ALL_SPACES(where, how, within) \ |
- CASE_STATEMENT(where, how, within, NEW_SPACE) \ |
- CASE_BODY(where, how, within, NEW_SPACE) \ |
- CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \ |
- CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \ |
- CASE_STATEMENT(where, how, within, CODE_SPACE) \ |
- CASE_STATEMENT(where, how, within, CELL_SPACE) \ |
- CASE_STATEMENT(where, how, within, PROPERTY_CELL_SPACE) \ |
- CASE_STATEMENT(where, how, within, MAP_SPACE) \ |
+#define ALL_SPACES(where, how, within) \ |
+ CASE_STATEMENT(where, how, within, NEW_SPACE) \ |
+ CASE_BODY(where, how, within, NEW_SPACE) \ |
+ CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \ |
+ CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \ |
+ CASE_STATEMENT(where, how, within, CODE_SPACE) \ |
+ CASE_STATEMENT(where, how, within, MAP_SPACE) \ |
+ CASE_STATEMENT(where, how, within, CELL_SPACE) \ |
+ CASE_STATEMENT(where, how, within, PROPERTY_CELL_SPACE) \ |
+ CASE_STATEMENT(where, how, within, LO_SPACE) \ |
CASE_BODY(where, how, within, kAnyOldSpace) |
#define FOUR_CASES(byte_code) \ |
@@ -1184,12 +1192,12 @@ Serializer::Serializer(Isolate* isolate, SnapshotByteSink* sink) |
sink_(sink), |
external_reference_encoder_(new ExternalReferenceEncoder(isolate)), |
root_index_wave_front_(0), |
- code_address_map_(NULL) { |
+ code_address_map_(NULL), |
+ seen_large_objects_index_(0), |
+ large_objects_total_size_(0) { |
// The serializer is meant to be used only to generate initial heap images |
// from a context in which there is only one isolate. |
- for (int i = 0; i <= LAST_SPACE; i++) { |
- fullness_[i] = 0; |
- } |
+ for (int i = 0; i < kNumberOfReservedSpaces; i++) fullness_[i] = 0; |
} |
@@ -1324,10 +1332,7 @@ void Serializer::SerializeReferenceToPreviousObject(HeapObject* heap_object, |
WhereToPoint where_to_point, |
int skip) { |
int space = SpaceOfObject(heap_object); |
- int address = address_mapper_.MappedTo(heap_object); |
- int offset = CurrentAllocationAddress(space) - address; |
- // Shift out the bits that are always 0. |
- offset >>= kObjectAlignmentBits; |
+ |
if (skip == 0) { |
sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer"); |
} else { |
@@ -1335,7 +1340,17 @@ void Serializer::SerializeReferenceToPreviousObject(HeapObject* heap_object, |
"BackRefSerWithSkip"); |
sink_->PutInt(skip, "BackRefSkipDistance"); |
} |
- sink_->PutInt(offset, "offset"); |
+ |
+ if (space == LO_SPACE) { |
+ int index = address_mapper_.MappedTo(heap_object); |
+ sink_->PutInt(index, "large object index"); |
+ } else { |
+ int address = address_mapper_.MappedTo(heap_object); |
+ int offset = CurrentAllocationAddress(space) - address; |
+ // Shift out the bits that are always 0. |
+ offset >>= kObjectAlignmentBits; |
+ sink_->PutInt(offset, "offset"); |
+ } |
} |
@@ -1494,8 +1509,18 @@ void Serializer::ObjectSerializer::Serialize() { |
} |
// Mark this object as already serialized. |
- int offset = serializer_->Allocate(space, size); |
- serializer_->address_mapper()->AddMapping(object_, offset); |
+ if (space == LO_SPACE) { |
+ if (object_->IsCode()) { |
+ sink_->PutInt(EXECUTABLE, "executable large object"); |
+ } else { |
+ sink_->PutInt(NOT_EXECUTABLE, "not executable large object"); |
+ } |
+ int index = serializer_->AllocateLargeObject(size); |
+ serializer_->address_mapper()->AddMapping(object_, index); |
+ } else { |
+ int offset = serializer_->Allocate(space, size); |
+ serializer_->address_mapper()->AddMapping(object_, offset); |
+ } |
// Serialize the map (first word of the object). |
serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject, 0); |
@@ -1747,8 +1772,14 @@ int Serializer::SpaceOfObject(HeapObject* object) { |
} |
+int Serializer::AllocateLargeObject(int size) { |
+ large_objects_total_size_ += size; |
+ return seen_large_objects_index_++; |
+} |
+ |
+ |
int Serializer::Allocate(int space, int size) { |
- CHECK(space >= 0 && space < kNumberOfSpaces); |
+ CHECK(space >= 0 && space < kNumberOfReservedSpaces); |
int allocation_address = fullness_[space]; |
fullness_[space] = allocation_address + size; |
return allocation_address; |
@@ -1840,11 +1871,11 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code, |
if (heap_object->IsCode()) { |
Code* code_object = Code::cast(heap_object); |
+ DCHECK(!code_object->is_optimized_code()); |
if (code_object->kind() == Code::BUILTIN) { |
SerializeBuiltin(code_object, how_to_code, where_to_point, skip); |
return; |
- } |
- if (code_object->IsCodeStubOrIC()) { |
+ } else if (code_object->IsCodeStubOrIC()) { |
SerializeCodeStub(code_object, how_to_code, where_to_point, skip); |
return; |
} |
@@ -1991,9 +2022,10 @@ Handle<SharedFunctionInfo> CodeSerializer::Deserialize(Isolate* isolate, |
SnapshotByteSource payload(scd.Payload(), scd.PayloadLength()); |
Deserializer deserializer(&payload); |
STATIC_ASSERT(NEW_SPACE == 0); |
- for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { |
+ for (int i = NEW_SPACE; i < kNumberOfReservedSpaces; i++) { |
deserializer.set_reservation(i, scd.GetReservation(i)); |
} |
+ deserializer.set_large_objects_total_size(scd.GetLargeObjectsTotalSize()); |
// Prepare and register list of attached objects. |
Vector<const uint32_t> code_stub_keys = scd.CodeStubKeys(); |
@@ -2040,8 +2072,9 @@ SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs) |
SetHeaderValue(kCheckSumOffset, CheckSum(cs->source())); |
SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys); |
SetHeaderValue(kPayloadLengthOffset, payload->length()); |
+ SetHeaderValue(kLargeObjectsTotalSizeOffset, cs->large_objects_total_size()); |
STATIC_ASSERT(NEW_SPACE == 0); |
- for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) { |
+ for (int i = 0; i < SerializerDeserializer::kNumberOfReservedSpaces; i++) { |
SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i)); |
} |