| 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));
|
| }
|
|
|
|
|