diff --git a/deps/v8/src/globals.h b/deps/v8/src/globals.h index e06257d35e..6f2b748e01 100644 --- a/deps/v8/src/globals.h +++ b/deps/v8/src/globals.h @@ -629,6 +629,8 @@ enum VisitMode { VISIT_ALL_IN_MINOR_MC_UPDATE, VISIT_ALL_IN_SCAVENGE, VISIT_ALL_IN_SWEEP_NEWSPACE, + VISIT_ALL_FOR_STARTUP_DESERIALIZATION, + VISIT_ALL_FOR_STARTUP_SERIALIZATION, VISIT_ONLY_STRONG, VISIT_ONLY_STRONG_FOR_SERIALIZATION, VISIT_ONLY_STRONG_ROOT_LIST, diff --git a/deps/v8/src/heap/heap-inl.h b/deps/v8/src/heap/heap-inl.h index 49d69c80e2..d558434850 100644 --- a/deps/v8/src/heap/heap-inl.h +++ b/deps/v8/src/heap/heap-inl.h @@ -25,6 +25,7 @@ #include "src/objects/scope-info.h" #include "src/objects/script-inl.h" #include "src/profiler/heap-profiler.h" +#include "src/snapshot/startup-serializer.h" #include "src/string-hasher.h" namespace v8 { @@ -585,6 +586,27 @@ void Heap::ExternalStringTable::IterateAll(RootVisitor* v) { } } +void Heap::ExternalStringTable::IterateAll(RootVisitor* v, VisitMode mode) { + if (mode == VISIT_ALL_FOR_STARTUP_DESERIALIZATION) { + StartupSerializer::IterateExternalStringTable(heap_->isolate_, &new_space_strings_, v); + StartupSerializer::IterateExternalStringTable(heap_->isolate_, &old_space_strings_, v); + } else if (mode == VISIT_ALL_FOR_STARTUP_SERIALIZATION) { + Object* undefined = heap_->undefined_value(); + IterateNewSpaceStrings(v); + // end sentinel + v->VisitRootPointer(Root::kExternalStringsTable, &undefined); + + if (!old_space_strings_.empty()) { + v->VisitRootPointers(Root::kExternalStringsTable, old_space_strings_.data(), + old_space_strings_.data() + old_space_strings_.size()); + } + // end sentinel + v->VisitRootPointer(Root::kExternalStringsTable, &undefined); + } else { + IterateAll(v); + } +} + // Verify() is inline to avoid ifdef-s around its calls in release // mode. diff --git a/deps/v8/src/heap/heap.cc b/deps/v8/src/heap/heap.cc index b13ec784f5..99725c9be5 100644 --- a/deps/v8/src/heap/heap.cc +++ b/deps/v8/src/heap/heap.cc @@ -5266,7 +5266,7 @@ void Heap::IterateWeakRoots(RootVisitor* v, VisitMode mode) { v->Synchronize(VisitorSynchronization::kStringTable); if (!isMinorGC && mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { // Scavenge collections have special processing for this. - external_string_table_.IterateAll(v); + external_string_table_.IterateAll(v, mode); } v->Synchronize(VisitorSynchronization::kExternalStringsTable); } diff --git a/deps/v8/src/heap/heap.h b/deps/v8/src/heap/heap.h index 7b87770385..adc7d5cb24 100644 --- a/deps/v8/src/heap/heap.h +++ b/deps/v8/src/heap/heap.h @@ -1564,6 +1564,7 @@ class Heap { inline void AddString(String* string); inline void IterateAll(RootVisitor* v); + inline void IterateAll(RootVisitor* v, VisitMode mode); inline void IterateNewSpaceStrings(RootVisitor* v); inline void PromoteAllNewSpaceStrings(); diff --git a/deps/v8/src/snapshot/startup-deserializer.cc b/deps/v8/src/snapshot/startup-deserializer.cc index 6746a02656..5934b7db27 100644 --- a/deps/v8/src/snapshot/startup-deserializer.cc +++ b/deps/v8/src/snapshot/startup-deserializer.cc @@ -30,7 +30,7 @@ void StartupDeserializer::DeserializeInto(Isolate* isolate) { isolate->heap()->IterateSmiRoots(this); isolate->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); isolate->heap()->RepairFreeListsAfterDeserialization(); - isolate->heap()->IterateWeakRoots(this, VISIT_ALL); + isolate->heap()->IterateWeakRoots(this, VISIT_ALL_FOR_STARTUP_DESERIALIZATION); DeserializeDeferredObjects(); FlushICacheForNewIsolate(); RestoreExternalReferenceRedirectors(accessor_infos()); diff --git a/deps/v8/src/snapshot/startup-serializer.cc b/deps/v8/src/snapshot/startup-serializer.cc index e2bd4ceadd..c36d8ef068 100644 --- a/deps/v8/src/snapshot/startup-serializer.cc +++ b/deps/v8/src/snapshot/startup-serializer.cc @@ -26,6 +26,17 @@ StartupSerializer::~StartupSerializer() { OutputStatistics("StartupSerializer"); } +void StartupSerializer::IterateExternalStringTable(Isolate* isolate, + std::vector* strings, + RootVisitor* visitor) { + for (size_t i = 0;; ++i) { + Object* obj; + visitor->VisitRootPointer(Root::kExternalStringsTable, &obj); + if (obj->IsUndefined(isolate)) break; + if (obj->IsExternalString()) strings->push_back(obj); + } +} + void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code, WhereToPoint where_to_point, int skip) { DCHECK(!obj->IsJSFunction()); @@ -87,7 +98,7 @@ void StartupSerializer::SerializeWeakReferencesAndDeferred() { // one entry with 'undefined' to terminate the partial snapshot cache. Object* undefined = isolate()->heap()->undefined_value(); VisitRootPointer(Root::kPartialSnapshotCache, &undefined); - isolate()->heap()->IterateWeakRoots(this, VISIT_ALL); + isolate()->heap()->IterateWeakRoots(this, VISIT_ALL_FOR_STARTUP_SERIALIZATION); SerializeDeferredObjects(); Pad(); } diff --git a/deps/v8/src/snapshot/startup-serializer.h b/deps/v8/src/snapshot/startup-serializer.h index c17fba2fb4..4f0ae39368 100644 --- a/deps/v8/src/snapshot/startup-serializer.h +++ b/deps/v8/src/snapshot/startup-serializer.h @@ -6,6 +6,7 @@ #define V8_SNAPSHOT_STARTUP_SERIALIZER_H_ #include +#include #include "include/v8.h" #include "src/snapshot/serializer.h" @@ -19,6 +20,9 @@ class StartupSerializer : public Serializer { v8::SnapshotCreator::FunctionCodeHandling function_code_handling); ~StartupSerializer() override; + static void IterateExternalStringTable(Isolate* isolate, + std::vector* strings, RootVisitor* visitor); + // Serialize the current state of the heap. The order is: // 1) Immortal immovable roots // 2) Remaining strong references.