// Copyright 2017 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/snapshot/object-deserializer.h" #include "src/codegen/assembler-inl.h" #include "src/execution/isolate.h" #include "src/execution/local-isolate-wrapper-inl.h" #include "src/heap/heap-inl.h" #include "src/objects/allocation-site-inl.h" #include "src/objects/objects.h" #include "src/objects/slots.h" #include "src/snapshot/code-serializer.h" namespace v8 { namespace internal { ObjectDeserializer::ObjectDeserializer(const SerializedCodeData* data) : Deserializer(data, true) {} MaybeHandle ObjectDeserializer::DeserializeSharedFunctionInfo( Isolate* isolate, const SerializedCodeData* data, Handle source) { ObjectDeserializer d(data); d.AddAttachedObject(source); Handle result; return d.Deserialize(LocalIsolateWrapper(isolate)).ToHandle(&result) ? Handle::cast(result) : MaybeHandle(); } MaybeHandle ObjectDeserializer::DeserializeSharedFunctionInfoOffThread( OffThreadIsolate* isolate, const SerializedCodeData* data, Handle source) { DCHECK(ReadOnlyHeap::Contains(*source) || Heap::InOffThreadSpace(*source)); ObjectDeserializer d(data); d.AddAttachedObject(source); Handle result; return d.Deserialize(LocalIsolateWrapper(isolate)).ToHandle(&result) ? Handle::cast(result) : MaybeHandle(); } MaybeHandle ObjectDeserializer::Deserialize( LocalIsolateWrapper local_isolate) { Initialize(local_isolate); if (!allocator()->ReserveSpace()) return MaybeHandle(); DCHECK(deserializing_user_code()); LocalHandleScopeWrapper scope(local_isolate); Handle result; { DisallowHeapAllocation no_gc; Object root; VisitRootPointer(Root::kStartupObjectCache, nullptr, FullObjectSlot(&root)); DeserializeDeferredObjects(); CHECK(new_code_objects().empty()); if (is_main_thread()) { LinkAllocationSites(); LogNewMapEvents(); } result = handle(HeapObject::cast(root), local_isolate); if (is_main_thread()) { allocator()->RegisterDeserializedObjectsForBlackAllocation(); } } Rehash(); CommitPostProcessedObjects(); return scope.CloseAndEscape(result); } void ObjectDeserializer::CommitPostProcessedObjects() { if (is_main_thread()) { CHECK_LE(new_internalized_strings().size(), kMaxInt); StringTable::EnsureCapacityForDeserialization( isolate(), static_cast(new_internalized_strings().size())); for (Handle string : new_internalized_strings()) { DisallowHeapAllocation no_gc; StringTableInsertionKey key(*string); StringTable::AddKeyNoResize(isolate(), &key); } for (Handle buffer : new_off_heap_array_buffers()) { uint32_t store_index = buffer->GetBackingStoreRefForDeserialization(); auto bs = backing_store(store_index); SharedFlag shared = bs && bs->is_shared() ? SharedFlag::kShared : SharedFlag::kNotShared; buffer->Setup(shared, bs); } } else { CHECK_EQ(new_internalized_strings().size(), 0); CHECK_EQ(new_off_heap_array_buffers().size(), 0); } for (Handle