1 // Copyright 2017 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/snapshot/object-deserializer.h" 6 7 #include "src/assembler-inl.h" 8 #include "src/code-stubs.h" 9 #include "src/isolate.h" 10 #include "src/objects.h" 11 #include "src/snapshot/code-serializer.h" 12 13 namespace v8 { 14 namespace internal { 15 16 MaybeHandle<SharedFunctionInfo> 17 ObjectDeserializer::DeserializeSharedFunctionInfo( 18 Isolate* isolate, const SerializedCodeData* data, Handle<String> source) { 19 ObjectDeserializer d(data); 20 21 d.AddAttachedObject(source); 22 23 Vector<const uint32_t> code_stub_keys = data->CodeStubKeys(); 24 for (int i = 0; i < code_stub_keys.length(); i++) { 25 d.AddAttachedObject( 26 CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked()); 27 } 28 29 Handle<HeapObject> result; 30 return d.Deserialize(isolate).ToHandle(&result) 31 ? Handle<SharedFunctionInfo>::cast(result) 32 : MaybeHandle<SharedFunctionInfo>(); 33 } 34 35 MaybeHandle<HeapObject> ObjectDeserializer::Deserialize(Isolate* isolate) { 36 Initialize(isolate); 37 38 if (!allocator()->ReserveSpace()) return MaybeHandle<HeapObject>(); 39 40 DCHECK(deserializing_user_code()); 41 HandleScope scope(isolate); 42 Handle<HeapObject> result; 43 { 44 DisallowHeapAllocation no_gc; 45 Object* root; 46 VisitRootPointer(Root::kPartialSnapshotCache, nullptr, &root); 47 DeserializeDeferredObjects(); 48 FlushICacheForNewCodeObjectsAndRecordEmbeddedObjects(); 49 result = handle(HeapObject::cast(root), isolate); 50 Rehash(); 51 allocator()->RegisterDeserializedObjectsForBlackAllocation(); 52 } 53 CommitPostProcessedObjects(); 54 return scope.CloseAndEscape(result); 55 } 56 57 void ObjectDeserializer:: 58 FlushICacheForNewCodeObjectsAndRecordEmbeddedObjects() { 59 DCHECK(deserializing_user_code()); 60 for (Code* code : new_code_objects()) { 61 // Record all references to embedded objects in the new code object. 62 WriteBarrierForCode(code); 63 Assembler::FlushICache(code->raw_instruction_start(), 64 code->raw_instruction_size()); 65 } 66 } 67 68 void ObjectDeserializer::CommitPostProcessedObjects() { 69 CHECK_LE(new_internalized_strings().size(), kMaxInt); 70 StringTable::EnsureCapacityForDeserialization( 71 isolate(), static_cast<int>(new_internalized_strings().size())); 72 for (Handle<String> string : new_internalized_strings()) { 73 DisallowHeapAllocation no_gc; 74 StringTableInsertionKey key(*string); 75 DCHECK_NULL(StringTable::ForwardStringIfExists(isolate(), &key, *string)); 76 StringTable::AddKeyNoResize(isolate(), &key); 77 } 78 79 Heap* heap = isolate()->heap(); 80 Factory* factory = isolate()->factory(); 81 for (Handle<Script> script : new_scripts()) { 82 // Assign a new script id to avoid collision. 83 script->set_id(isolate()->heap()->NextScriptId()); 84 LOG(isolate(), 85 ScriptEvent(Logger::ScriptEventType::kDeserialize, script->id())); 86 LOG(isolate(), ScriptDetails(*script)); 87 // Add script to list. 88 Handle<WeakArrayList> list = factory->script_list(); 89 list = WeakArrayList::AddToEnd(isolate(), list, 90 MaybeObjectHandle::Weak(script)); 91 heap->SetRootScriptList(*list); 92 } 93 } 94 95 } // namespace internal 96 } // namespace v8 97