| Index: src/serialize.cc
|
| diff --git a/src/serialize.cc b/src/serialize.cc
|
| index 9d59b6fd4ff51da65939ed77a5c0eba333649ed9..04193b21a98eab4d24e3cde7deaf70c881b9e67f 100644
|
| --- a/src/serialize.cc
|
| +++ b/src/serialize.cc
|
| @@ -834,6 +834,7 @@ Address Deserializer::Allocate(int space_index, int size) {
|
| }
|
| }
|
|
|
| +
|
| void Deserializer::ReadChunk(Object** current,
|
| Object** limit,
|
| int source_space,
|
| @@ -1514,10 +1515,8 @@ void PartialSerializer::SerializeObject(
|
| }
|
|
|
|
|
| -void Serializer::ObjectSerializer::Serialize() {
|
| - int space = Serializer::SpaceOfObject(object_);
|
| - int size = object_->Size();
|
| -
|
| +void Serializer::ObjectSerializer::SerializePrologue(int space, int size,
|
| + Map* map) {
|
| sink_->Put(kNewObject + reference_representation_ + space,
|
| "ObjectSerialization");
|
| sink_->PutInt(size >> kObjectAlignmentBits, "Size in words");
|
| @@ -1546,13 +1545,79 @@ void Serializer::ObjectSerializer::Serialize() {
|
| }
|
|
|
| // Serialize the map (first word of the object).
|
| - serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject, 0);
|
| + serializer_->SerializeObject(map, kPlain, kStartOfObject, 0);
|
| +}
|
| +
|
| +
|
| +void Serializer::ObjectSerializer::SerializeExternalString() {
|
| + // Instead of serializing this as an external string, we serialize
|
| + // an imaginary sequential string with the same content.
|
| + DCHECK(object_->IsExternalString() && object_->IsInternalizedString());
|
| + Isolate* isolate = serializer_->isolate();
|
| + ExternalString* string = ExternalString::cast(object_);
|
| + int length = string->length();
|
| + Map* map;
|
| + int size;
|
| + const char* resource;
|
| + // Find the map and size for the imaginary sequential string.
|
| + if (object_->IsExternalOneByteString()) {
|
| + map = isolate->heap()->one_byte_internalized_string_map();
|
| + size = SeqOneByteString::SizeFor(length);
|
| + resource = ExternalOneByteString::cast(string)->resource()->data();
|
| + } else {
|
| + map = isolate->heap()->internalized_string_map();
|
| + size = SeqTwoByteString::SizeFor(length);
|
| + resource = reinterpret_cast<const char*>(
|
| + ExternalTwoByteString::cast(string)->resource()->data());
|
| + }
|
| +
|
| + int space =
|
| + (size > Page::kMaxRegularHeapObjectSize) ? LO_SPACE : OLD_DATA_SPACE;
|
| + SerializePrologue(space, size, map);
|
|
|
| - // Serialize the rest of the object.
|
| - CHECK_EQ(0, bytes_processed_so_far_);
|
| - bytes_processed_so_far_ = kPointerSize;
|
| - object_->IterateBody(object_->map()->instance_type(), size, this);
|
| - OutputRawData(object_->address() + size);
|
| + // Output the rest of the imaginary string.
|
| + int bytes_to_output = size - HeapObject::kHeaderSize;
|
| +
|
| + // Output raw data header. Do not bother with common raw length cases here.
|
| + sink_->Put(kRawData, "RawDataForString");
|
| + sink_->PutInt(bytes_to_output, "length");
|
| +
|
| + // Serialize string header (except for map).
|
| + Address string_start = string->address();
|
| + for (int i = HeapObject::kHeaderSize; i < SeqString::kHeaderSize; i++) {
|
| + sink_->PutSection(string_start[i], "StringHeader");
|
| + }
|
| +
|
| + // Serialize string content.
|
| + int content_length = size - SeqString::kHeaderSize;
|
| + for (int i = 0; i < content_length; i++) {
|
| + sink_->PutSection(resource[i], "StringContent");
|
| + }
|
| +
|
| + sink_->Put(kSkip, "SkipAfterString");
|
| + sink_->PutInt(bytes_to_output, "SkipDistance");
|
| +}
|
| +
|
| +
|
| +void Serializer::ObjectSerializer::Serialize() {
|
| + if (object_->IsExternalString() && object_->IsInternalizedString()) {
|
| + // Native source code strings are not internalized and are handled in
|
| + // VisitExternalOneByteString. We deal with embedded external strings
|
| + // by serializing them as sequential strings on the heap.
|
| + // This can only happen with CodeSerializer.
|
| + SerializeExternalString();
|
| + } else {
|
| + int size = object_->Size();
|
| + Map* map = object_->map();
|
| + SerializePrologue(Serializer::SpaceOfObject(object_), size, map);
|
| +
|
| + // Serialize the rest of the object.
|
| + CHECK_EQ(0, bytes_processed_so_far_);
|
| + bytes_processed_so_far_ = kPointerSize;
|
| +
|
| + object_->IterateBody(map->instance_type(), size, this);
|
| + OutputRawData(object_->address() + size);
|
| + }
|
| }
|
|
|
|
|
| @@ -1697,7 +1762,7 @@ void Serializer::ObjectSerializer::VisitExternalOneByteString(
|
| }
|
| }
|
| // One of the strings in the natives cache should match the resource. We
|
| - // can't serialize any other kinds of external strings.
|
| + // don't expect any other kinds of external strings here.
|
| UNREACHABLE();
|
| }
|
|
|
| @@ -1876,6 +1941,11 @@ void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
|
| }
|
|
|
| if (address_mapper_.IsMapped(heap_object)) {
|
| + if (FLAG_trace_code_serializer) {
|
| + PrintF("Encoding back reference to: ");
|
| + heap_object->ShortPrint();
|
| + PrintF("\n");
|
| + }
|
| SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point,
|
| skip);
|
| return;
|
|
|