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) { |