Index: src/snapshot/serialize.cc |
diff --git a/src/snapshot/serialize.cc b/src/snapshot/serialize.cc |
index e7976aca6fb6821f4b406ce03c696fd3ecf9db1f..fceec47fae6daab3b74a9896905c0f3d552c1cb5 100644 |
--- a/src/snapshot/serialize.cc |
+++ b/src/snapshot/serialize.cc |
@@ -1372,6 +1372,66 @@ void Serializer::OutputStatistics(const char* name) { |
} |
+class Serializer::ObjectSerializer : public ObjectVisitor { |
+ public: |
+ ObjectSerializer(Serializer* serializer, Object* o, SnapshotByteSink* sink, |
+ HowToCode how_to_code, WhereToPoint where_to_point) |
+ : serializer_(serializer), |
+ object_(HeapObject::cast(o)), |
+ sink_(sink), |
+ reference_representation_(how_to_code + where_to_point), |
+ bytes_processed_so_far_(0), |
+ is_code_object_(o->IsCode()), |
+ code_has_been_output_(false) {} |
+ void Serialize(); |
+ void SerializeDeferred(); |
+ void VisitPointers(Object** start, Object** end); |
+ void VisitEmbeddedPointer(RelocInfo* target); |
+ void VisitExternalReference(Address* p); |
+ void VisitExternalReference(RelocInfo* rinfo); |
+ void VisitInternalReference(RelocInfo* rinfo); |
+ void VisitCodeTarget(RelocInfo* target); |
+ void VisitCodeEntry(Address entry_address); |
+ void VisitCell(RelocInfo* rinfo); |
+ void VisitRuntimeEntry(RelocInfo* reloc); |
+ // Used for seralizing the external strings that hold the natives source. |
+ void VisitExternalOneByteString( |
+ v8::String::ExternalOneByteStringResource** resource); |
+ // We can't serialize a heap with external two byte strings. |
+ void VisitExternalTwoByteString( |
+ v8::String::ExternalStringResource** resource) { |
+ UNREACHABLE(); |
+ } |
+ |
+ private: |
+ void SerializePrologue(AllocationSpace space, int size, Map* map); |
+ |
+ bool SerializeExternalNativeSourceString( |
+ int builtin_count, |
+ v8::String::ExternalOneByteStringResource** resource_pointer, |
+ FixedArray* source_cache, int resource_index); |
+ |
+ enum ReturnSkip { kCanReturnSkipInsteadOfSkipping, kIgnoringReturn }; |
+ // This function outputs or skips the raw data between the last pointer and |
+ // up to the current position. It optionally can just return the number of |
+ // bytes to skip instead of performing a skip instruction, in case the skip |
+ // can be merged into the next instruction. |
+ int OutputRawData(Address up_to, ReturnSkip return_skip = kIgnoringReturn); |
+ // External strings are serialized in a way to resemble sequential strings. |
+ void SerializeExternalString(); |
+ |
+ Address PrepareCode(); |
+ |
+ Serializer* serializer_; |
+ HeapObject* object_; |
+ SnapshotByteSink* sink_; |
+ int reference_representation_; |
+ int bytes_processed_so_far_; |
+ bool is_code_object_; |
+ bool code_has_been_output_; |
+}; |
+ |
+ |
void Serializer::SerializeDeferredObjects() { |
while (deferred_objects_.length() > 0) { |
HeapObject* obj = deferred_objects_.RemoveLast(); |
@@ -1533,6 +1593,11 @@ void SerializerDeserializer::Iterate(Isolate* isolate, |
} |
+bool SerializerDeserializer::CanBeDeferred(HeapObject* o) { |
+ return !o->IsString() && !o->IsScript(); |
+} |
+ |
+ |
int PartialSerializer::PartialSnapshotCacheIndex(HeapObject* heap_object) { |
Isolate* isolate = this->isolate(); |
List<Object*>* cache = isolate->partial_snapshot_cache(); |
@@ -1553,6 +1618,19 @@ int PartialSerializer::PartialSnapshotCacheIndex(HeapObject* heap_object) { |
} |
+bool PartialSerializer::ShouldBeInThePartialSnapshotCache(HeapObject* o) { |
+ // Scripts should be referred only through shared function infos. We can't |
+ // allow them to be part of the partial snapshot because they contain a |
+ // unique ID, and deserializing several partial snapshots containing script |
+ // would cause dupes. |
+ DCHECK(!o->IsScript()); |
+ return o->IsName() || o->IsSharedFunctionInfo() || o->IsHeapNumber() || |
+ o->IsCode() || o->IsScopeInfo() || o->IsExecutableAccessorInfo() || |
+ o->map() == |
+ startup_serializer_->isolate()->heap()->fixed_cow_array_map(); |
+} |
+ |
+ |
#ifdef DEBUG |
bool Serializer::BackReferenceIsAlreadyAllocated(BackReference reference) { |
DCHECK(reference.is_valid()); |
@@ -1636,6 +1714,17 @@ bool Serializer::SerializeKnownObject(HeapObject* obj, HowToCode how_to_code, |
} |
+StartupSerializer::StartupSerializer(Isolate* isolate, SnapshotByteSink* sink) |
+ : Serializer(isolate, sink), root_index_wave_front_(0) { |
+ // Clear the cache of objects used by the partial snapshot. After the |
+ // strong roots have been serialized we can create a partial snapshot |
+ // which will repopulate the cache with objects needed by that partial |
+ // snapshot. |
+ isolate->partial_snapshot_cache()->Clear(); |
+ InitializeCodeAddressMap(); |
+} |
+ |
+ |
void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, |
WhereToPoint where_to_point, int skip) { |
// Make sure that all functions are derived from the code-stub context |
@@ -2730,6 +2819,11 @@ SerializedCodeData::SanityCheckResult SerializedCodeData::SanityCheck( |
} |
+uint32_t SerializedCodeData::SourceHash(String* source) const { |
+ return source->length(); |
+} |
+ |
+ |
// Return ScriptData object and relinquish ownership over it to the caller. |
ScriptData* SerializedCodeData::GetScriptData() { |
DCHECK(owns_data_); |