Chromium Code Reviews| Index: src/snapshot/serializer.cc |
| diff --git a/src/snapshot/serializer.cc b/src/snapshot/serializer.cc |
| index 5f9002e4e34fc65d77ccbdbab8b2e618e09288f6..e826a29fd32b282a12ff82b1572dc663f1377d09 100644 |
| --- a/src/snapshot/serializer.cc |
| +++ b/src/snapshot/serializer.cc |
| @@ -401,6 +401,69 @@ void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space, |
| } |
| void Serializer::ObjectSerializer::SerializeExternalString() { |
| + Heap* heap = serializer_->isolate()->heap(); |
| + if (object_->map() != heap->native_source_string_map()) { |
| + // Usually we cannot recreate resources for external strings. To work |
| + // around this, external strings are serialized to look like ordinary |
| + // sequential strings. |
| + // The exception are native source code strings, since we can recreate |
| + // their resources. |
| + SerializeExternalStringAsSequentialString(); |
| + } else { |
| + DCHECK(object_->IsExternalOneByteString()); |
| + DCHECK(ExternalOneByteString::cast(object_)->is_short()); |
| + int size = object_->Size(); |
| + Map* map = object_->map(); |
| + AllocationSpace space = |
| + MemoryChunk::FromAddress(object_->address())->owner()->identity(); |
| + SerializePrologue(space, size, map); |
| + // Serialize the rest of the object. |
| + CHECK_EQ(0, bytes_processed_so_far_); |
|
ulan
2017/04/06 17:53:08
Lines 413-421 are from the Serialize function.
Th
|
| + bytes_processed_so_far_ = kPointerSize; |
| + typedef v8::String::ExternalOneByteStringResource Resource; |
| + Resource** resource_pointer = reinterpret_cast<Resource**>( |
| + HeapObject::RawField(object_, ExternalString::kResourceOffset)); |
| + |
| + Address references_start = reinterpret_cast<Address>(resource_pointer); |
| + OutputRawData(references_start); |
| + if (!SerializeExternalNativeSourceString( |
| + Natives::GetBuiltinsCount(), resource_pointer, |
| + Natives::GetSourceCache(heap), kNativesStringResource)) { |
| + bool result = SerializeExternalNativeSourceString( |
| + ExtraNatives::GetBuiltinsCount(), resource_pointer, |
| + ExtraNatives::GetSourceCache(heap), kExtraNativesStringResource); |
| + // One of the strings in the natives cache should match the resource. We |
| + // don't expect any other kinds of external strings here. |
| + USE(result); |
| + DCHECK(result); |
| + } |
| + OutputRawData(object_->address() + size); |
| + } |
| +} |
| + |
| +bool Serializer::ObjectSerializer::SerializeExternalNativeSourceString( |
| + int builtin_count, |
| + v8::String::ExternalOneByteStringResource** resource_pointer, |
| + FixedArray* source_cache, int resource_index) { |
| + Isolate* isolate = serializer_->isolate(); |
|
ulan
2017/04/06 17:53:08
This function moved without any change.
|
| + for (int i = 0; i < builtin_count; i++) { |
| + Object* source = source_cache->get(i); |
| + if (!source->IsUndefined(isolate)) { |
| + ExternalOneByteString* string = ExternalOneByteString::cast(source); |
| + typedef v8::String::ExternalOneByteStringResource Resource; |
| + const Resource* resource = string->resource(); |
| + if (resource == *resource_pointer) { |
| + sink_->Put(resource_index, "NativesStringResource"); |
| + sink_->PutSection(i, "NativesStringResourceEnd"); |
| + bytes_processed_so_far_ += sizeof(resource); |
| + return true; |
| + } |
| + } |
| + } |
| + return false; |
| +} |
| + |
| +void Serializer::ObjectSerializer::SerializeExternalStringAsSequentialString() { |
| // Instead of serializing this as an external string, we serialize |
| // an imaginary sequential string with the same content. |
| Isolate* isolate = serializer_->isolate(); |
| @@ -501,55 +564,45 @@ void Serializer::ObjectSerializer::Serialize() { |
| PrintF("\n"); |
| } |
| - // We cannot serialize typed array objects correctly. |
| - DCHECK(!object_->IsJSTypedArray()); |
| + if (object_->IsExternalString()) { |
| + SerializeExternalString(); |
| + } else { |
| + // We cannot serialize typed array objects correctly. |
| + DCHECK(!object_->IsJSTypedArray()); |
| - // We don't expect fillers. |
| - DCHECK(!object_->IsFiller()); |
| + // We don't expect fillers. |
| + DCHECK(!object_->IsFiller()); |
| - if (object_->IsScript()) { |
| - // Clear cached line ends. |
| - Object* undefined = serializer_->isolate()->heap()->undefined_value(); |
| - Script::cast(object_)->set_line_ends(undefined); |
| - } |
| + if (object_->IsScript()) { |
| + // Clear cached line ends. |
| + Object* undefined = serializer_->isolate()->heap()->undefined_value(); |
| + Script::cast(object_)->set_line_ends(undefined); |
| + } |
| - if (object_->IsExternalString()) { |
| - Heap* heap = serializer_->isolate()->heap(); |
| - if (object_->map() != heap->native_source_string_map()) { |
| - // Usually we cannot recreate resources for external strings. To work |
| - // around this, external strings are serialized to look like ordinary |
| - // sequential strings. |
| - // The exception are native source code strings, since we can recreate |
| - // their resources. In that case we fall through and leave it to |
| - // VisitExternalOneByteString further down. |
| - SerializeExternalString(); |
| + int size = object_->Size(); |
|
ulan
2017/04/06 17:53:08
This code just moved verbatim from 529.
|
| + Map* map = object_->map(); |
| + AllocationSpace space = |
| + MemoryChunk::FromAddress(object_->address())->owner()->identity(); |
| + SerializePrologue(space, size, map); |
| + |
| + // Serialize the rest of the object. |
| + CHECK_EQ(0, bytes_processed_so_far_); |
| + bytes_processed_so_far_ = kPointerSize; |
| + |
| + RecursionScope recursion(serializer_); |
| + // Objects that are immediately post processed during deserialization |
| + // cannot be deferred, since post processing requires the object content. |
| + if (recursion.ExceedsMaximum() && CanBeDeferred(object_)) { |
| + serializer_->QueueDeferredObject(object_); |
| + sink_->Put(kDeferred, "Deferring object content"); |
| return; |
| } |
| - } |
| - |
| - int size = object_->Size(); |
| - Map* map = object_->map(); |
| - AllocationSpace space = |
| - MemoryChunk::FromAddress(object_->address())->owner()->identity(); |
| - SerializePrologue(space, size, map); |
| - // Serialize the rest of the object. |
| - CHECK_EQ(0, bytes_processed_so_far_); |
| - bytes_processed_so_far_ = kPointerSize; |
| + UnlinkWeakNextScope unlink_weak_next(object_); |
| - RecursionScope recursion(serializer_); |
| - // Objects that are immediately post processed during deserialization |
| - // cannot be deferred, since post processing requires the object content. |
| - if (recursion.ExceedsMaximum() && CanBeDeferred(object_)) { |
| - serializer_->QueueDeferredObject(object_); |
| - sink_->Put(kDeferred, "Deferring object content"); |
| - return; |
| + object_->IterateBody(map->instance_type(), size, this); |
| + OutputRawData(object_->address() + size); |
| } |
| - |
| - UnlinkWeakNextScope unlink_weak_next(object_); |
| - |
| - object_->IterateBody(map->instance_type(), size, this); |
| - OutputRawData(object_->address() + size); |
| } |
| void Serializer::ObjectSerializer::SerializeDeferred() { |
| @@ -715,52 +768,6 @@ void Serializer::ObjectSerializer::VisitCell(RelocInfo* rinfo) { |
| bytes_processed_so_far_ += kPointerSize; |
| } |
| -bool Serializer::ObjectSerializer::SerializeExternalNativeSourceString( |
| - int builtin_count, |
| - v8::String::ExternalOneByteStringResource** resource_pointer, |
| - FixedArray* source_cache, int resource_index) { |
| - Isolate* isolate = serializer_->isolate(); |
| - for (int i = 0; i < builtin_count; i++) { |
| - Object* source = source_cache->get(i); |
| - if (!source->IsUndefined(isolate)) { |
| - ExternalOneByteString* string = ExternalOneByteString::cast(source); |
| - typedef v8::String::ExternalOneByteStringResource Resource; |
| - const Resource* resource = string->resource(); |
| - if (resource == *resource_pointer) { |
| - sink_->Put(resource_index, "NativesStringResource"); |
| - sink_->PutSection(i, "NativesStringResourceEnd"); |
| - bytes_processed_so_far_ += sizeof(resource); |
| - return true; |
| - } |
| - } |
| - } |
| - return false; |
| -} |
| - |
| -void Serializer::ObjectSerializer::VisitExternalOneByteString( |
| - v8::String::ExternalOneByteStringResource** resource_pointer) { |
| - DCHECK_EQ(serializer_->isolate()->heap()->native_source_string_map(), |
| - object_->map()); |
| - DCHECK(ExternalOneByteString::cast(object_)->is_short()); |
| - Address references_start = reinterpret_cast<Address>(resource_pointer); |
| - OutputRawData(references_start); |
| - if (SerializeExternalNativeSourceString( |
| - Natives::GetBuiltinsCount(), resource_pointer, |
| - Natives::GetSourceCache(serializer_->isolate()->heap()), |
| - kNativesStringResource)) { |
| - return; |
| - } |
| - if (SerializeExternalNativeSourceString( |
| - ExtraNatives::GetBuiltinsCount(), resource_pointer, |
| - ExtraNatives::GetSourceCache(serializer_->isolate()->heap()), |
| - kExtraNativesStringResource)) { |
| - return; |
| - } |
| - // One of the strings in the natives cache should match the resource. We |
| - // don't expect any other kinds of external strings here. |
| - UNREACHABLE(); |
| -} |
| - |
| Address Serializer::ObjectSerializer::PrepareCode() { |
| Code* code = Code::cast(object_); |
| if (FLAG_predictable) { |