diff --git a/src/snapshot/code-serializer.cc b/src/snapshot/code-serializer.cc index a597713428..eb9510e697 100644 --- a/src/snapshot/code-serializer.cc +++ b/src/snapshot/code-serializer.cc @@ -194,7 +194,7 @@ MaybeHandle CodeSerializer::Deserialize( return MaybeHandle(); } - ObjectDeserializer deserializer(&scd, false); + ObjectDeserializer deserializer(&scd); deserializer.AddAttachedObject(source); Vector code_stub_keys = scd.CodeStubKeys(); for (int i = 0; i < code_stub_keys.length(); i++) { @@ -265,7 +265,7 @@ MaybeHandle WasmCompiledModuleSerializer::DeserializeWasmModule( return nothing; } - ObjectDeserializer deserializer(&scd, true); + ObjectDeserializer deserializer(&scd); deserializer.AddAttachedObject(isolate->native_context()); MaybeHandle maybe_wire_bytes_as_string = diff --git a/src/snapshot/deserializer.cc b/src/snapshot/deserializer.cc index 27d9ca7b54..7bde40314c 100644 --- a/src/snapshot/deserializer.cc +++ b/src/snapshot/deserializer.cc @@ -33,25 +33,9 @@ void Deserializer::DecodeReservation( for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0; } -void Deserializer::FlushICacheForNewIsolate() { - DCHECK(!deserializing_user_code_); - // The entire isolate is newly deserialized. Simply flush all code pages. - for (Page* p : *isolate_->heap()->code_space()) { - Assembler::FlushICache(isolate_, p->area_start(), - p->area_end() - p->area_start()); - } -} - -void Deserializer::FlushICacheForNewCodeObjectsAndRecordEmbeddedObjects() { - DCHECK(deserializing_user_code_); - for (Code* code : new_code_objects_) { - // Record all references to embedded objects in the new code object. - isolate_->heap()->RecordWritesIntoCode(code); - - if (FLAG_serialize_age_code) code->PreAge(isolate_); - Assembler::FlushICache(isolate_, code->instruction_start(), - code->instruction_size()); - } +void Deserializer::RegisterDeserializedObjectsForBlackAllocation() { + isolate_->heap()->RegisterDeserializedObjectsForBlackAllocation( + reservations_, &deserialized_large_objects_, &allocated_maps_); } bool Deserializer::ReserveSpace() { @@ -83,126 +67,6 @@ void Deserializer::Initialize(Isolate* isolate) { SerializedData::GetExtraReferences(external_reference_table_)); } -void Deserializer::Deserialize(Isolate* isolate) { - Initialize(isolate); - if (!ReserveSpace()) V8::FatalProcessOutOfMemory("deserializing context"); - // No active threads. - DCHECK_NULL(isolate_->thread_manager()->FirstThreadStateInUse()); - // No active handles. - DCHECK(isolate_->handle_scope_implementer()->blocks()->is_empty()); - // Partial snapshot cache is not yet populated. - DCHECK(isolate_->partial_snapshot_cache()->is_empty()); - // Builtins are not yet created. - DCHECK(!isolate_->builtins()->is_initialized()); - - { - DisallowHeapAllocation no_gc; - isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG_ROOT_LIST); - isolate_->heap()->IterateSmiRoots(this); - isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG); - isolate_->heap()->RepairFreeListsAfterDeserialization(); - isolate_->heap()->IterateWeakRoots(this, VISIT_ALL); - DeserializeDeferredObjects(); - FlushICacheForNewIsolate(); - RestoreExternalReferenceRedirectors(&accessor_infos_); - } - - isolate_->heap()->set_native_contexts_list( - isolate_->heap()->undefined_value()); - // The allocation site list is build during root iteration, but if no sites - // were encountered then it needs to be initialized to undefined. - if (isolate_->heap()->allocation_sites_list() == Smi::kZero) { - isolate_->heap()->set_allocation_sites_list( - isolate_->heap()->undefined_value()); - } - - // Issue code events for newly deserialized code objects. - LOG_CODE_EVENT(isolate_, LogCodeObjects()); - LOG_CODE_EVENT(isolate_, LogBytecodeHandlers()); - LOG_CODE_EVENT(isolate_, LogCompiledFunctions()); - - isolate_->builtins()->MarkInitialized(); - - // If needed, print the dissassembly of deserialized code objects. - // Needs to be called after the builtins are marked as initialized, in order - // to display the builtin names. - PrintDisassembledCodeObjects(); - - if (FLAG_rehash_snapshot && can_rehash_) Rehash(); -} - -MaybeHandle Deserializer::DeserializePartial( - Isolate* isolate, Handle global_proxy, - v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) { - Initialize(isolate); - if (!ReserveSpace()) { - V8::FatalProcessOutOfMemory("deserialize context"); - return MaybeHandle(); - } - - AddAttachedObject(global_proxy); - - DisallowHeapAllocation no_gc; - // Keep track of the code space start and end pointers in case new - // code objects were unserialized - OldSpace* code_space = isolate_->heap()->code_space(); - Address start_address = code_space->top(); - Object* root; - VisitRootPointer(Root::kPartialSnapshotCache, &root); - DeserializeDeferredObjects(); - DeserializeEmbedderFields(embedder_fields_deserializer); - - isolate->heap()->RegisterDeserializedObjectsForBlackAllocation( - reservations_, &deserialized_large_objects_, &allocated_maps_); - - // There's no code deserialized here. If this assert fires then that's - // changed and logging should be added to notify the profiler et al of the - // new code, which also has to be flushed from instruction cache. - CHECK_EQ(start_address, code_space->top()); - - if (FLAG_rehash_snapshot && can_rehash_) RehashContext(Context::cast(root)); - - return Handle(root, isolate); -} - -MaybeHandle Deserializer::DeserializeObject(Isolate* isolate) { - Initialize(isolate); - if (!ReserveSpace()) { - return MaybeHandle(); - } else { - deserializing_user_code_ = true; - HandleScope scope(isolate); - Handle result; - { - DisallowHeapAllocation no_gc; - Object* root; - VisitRootPointer(Root::kPartialSnapshotCache, &root); - DeserializeDeferredObjects(); - FlushICacheForNewCodeObjectsAndRecordEmbeddedObjects(); - result = Handle(HeapObject::cast(root)); - isolate->heap()->RegisterDeserializedObjectsForBlackAllocation( - reservations_, &deserialized_large_objects_, &allocated_maps_); - } - CommitPostProcessedObjects(isolate); - return scope.CloseAndEscape(result); - } -} - -void Deserializer::Rehash() { - DCHECK(can_rehash_); - isolate_->heap()->InitializeHashSeed(); - isolate_->heap()->string_table()->Rehash(); - isolate_->heap()->weak_object_to_code_table()->Rehash(); - SortMapDescriptors(); -} - -void Deserializer::RehashContext(Context* context) { - DCHECK(can_rehash_); - for (const auto& array : transition_arrays_) array->Sort(); - context->global_object()->global_dictionary()->Rehash(); - SortMapDescriptors(); -} - void Deserializer::SortMapDescriptors() { for (const auto& address : allocated_maps_) { Map* map = Map::cast(HeapObject::FromAddress(address)); @@ -266,81 +130,28 @@ void Deserializer::DeserializeDeferredObjects() { } } -void Deserializer::DeserializeEmbedderFields( - v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) { - if (!source_.HasMore() || source_.Get() != kEmbedderFieldsData) return; - DisallowHeapAllocation no_gc; - DisallowJavascriptExecution no_js(isolate_); - DisallowCompilation no_compile(isolate_); - DCHECK_NOT_NULL(embedder_fields_deserializer.callback); - for (int code = source_.Get(); code != kSynchronize; code = source_.Get()) { - HandleScope scope(isolate_); - int space = code & kSpaceMask; - DCHECK(space <= kNumberOfSpaces); - DCHECK(code - space == kNewObject); - Handle obj(JSObject::cast(GetBackReferencedObject(space)), - isolate_); - int index = source_.GetInt(); - int size = source_.GetInt(); - byte* data = new byte[size]; - source_.CopyRaw(data, size); - embedder_fields_deserializer.callback(v8::Utils::ToLocal(obj), index, - {reinterpret_cast(data), size}, - embedder_fields_deserializer.data); - delete[] data; - } +StringTableInsertionKey::StringTableInsertionKey(String* string) + : StringTableKey(ComputeHashField(string)), string_(string) { + DCHECK(string->IsInternalizedString()); } -void Deserializer::PrintDisassembledCodeObjects() { -#ifdef ENABLE_DISASSEMBLER - if (FLAG_print_builtin_code) { - Heap* heap = isolate_->heap(); - HeapIterator iterator(heap); - DisallowHeapAllocation no_gc; - - CodeTracer::Scope tracing_scope(isolate_->GetCodeTracer()); - OFStream os(tracing_scope.file()); - - for (HeapObject* obj = iterator.next(); obj != NULL; - obj = iterator.next()) { - if (obj->IsCode()) { - Code::cast(obj)->Disassemble(nullptr, os); - } - } - } -#endif +bool StringTableInsertionKey::IsMatch(Object* string) { + // We know that all entries in a hash table had their hash keys created. + // Use that knowledge to have fast failure. + if (Hash() != String::cast(string)->Hash()) return false; + // We want to compare the content of two internalized strings here. + return string_->SlowEquals(String::cast(string)); } -// Used to insert a deserialized internalized string into the string table. -class StringTableInsertionKey : public StringTableKey { - public: - explicit StringTableInsertionKey(String* string) - : StringTableKey(ComputeHashField(string)), string_(string) { - DCHECK(string->IsInternalizedString()); - } +Handle StringTableInsertionKey::AsHandle(Isolate* isolate) { + return handle(string_, isolate); +} - bool IsMatch(Object* string) override { - // We know that all entries in a hash table had their hash keys created. - // Use that knowledge to have fast failure. - if (Hash() != String::cast(string)->Hash()) return false; - // We want to compare the content of two internalized strings here. - return string_->SlowEquals(String::cast(string)); - } - - MUST_USE_RESULT Handle AsHandle(Isolate* isolate) override { - return handle(string_, isolate); - } - - private: - uint32_t ComputeHashField(String* string) { - // Make sure hash_field() is computed. - string->Hash(); - return string->hash_field(); - } - - String* string_; - DisallowHeapAllocation no_gc; -}; +uint32_t StringTableInsertionKey::ComputeHashField(String* string) { + // Make sure hash_field() is computed. + string->Hash(); + return string->hash_field(); +} HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) { if (deserializing_user_code()) { @@ -415,26 +226,6 @@ HeapObject* Deserializer::PostProcessNewObject(HeapObject* obj, int space) { return obj; } -void Deserializer::CommitPostProcessedObjects(Isolate* isolate) { - StringTable::EnsureCapacityForDeserialization( - isolate, new_internalized_strings_.length()); - for (Handle string : new_internalized_strings_) { - StringTableInsertionKey key(*string); - DCHECK_NULL(StringTable::LookupKeyIfExists(isolate, &key)); - StringTable::LookupKey(isolate, &key); - } - - Heap* heap = isolate->heap(); - Factory* factory = isolate->factory(); - for (Handle