| // 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/assembler-inl.h" |
| #include "src/code-stubs.h" |
| #include "src/isolate.h" |
| #include "src/objects.h" |
| #include "src/snapshot/code-serializer.h" |
| #include "src/wasm/wasm-objects.h" |
| |
| namespace v8 { |
| namespace internal { |
| |
| MaybeHandle<SharedFunctionInfo> |
| ObjectDeserializer::DeserializeSharedFunctionInfo( |
| Isolate* isolate, const SerializedCodeData* data, Handle<String> source) { |
| ObjectDeserializer d(data); |
| |
| d.AddAttachedObject(source); |
| |
| Vector<const uint32_t> code_stub_keys = data->CodeStubKeys(); |
| for (int i = 0; i < code_stub_keys.length(); i++) { |
| d.AddAttachedObject( |
| CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked()); |
| } |
| |
| Handle<HeapObject> result; |
| return d.Deserialize(isolate).ToHandle(&result) |
| ? Handle<SharedFunctionInfo>::cast(result) |
| : MaybeHandle<SharedFunctionInfo>(); |
| } |
| |
| MaybeHandle<WasmCompiledModule> |
| ObjectDeserializer::DeserializeWasmCompiledModule( |
| Isolate* isolate, const SerializedCodeData* data, |
| Vector<const byte> wire_bytes) { |
| ObjectDeserializer d(data); |
| |
| d.AddAttachedObject(isolate->native_context()); |
| |
| MaybeHandle<String> maybe_wire_bytes_as_string = |
| isolate->factory()->NewStringFromOneByte(wire_bytes, TENURED); |
| Handle<String> wire_bytes_as_string; |
| if (!maybe_wire_bytes_as_string.ToHandle(&wire_bytes_as_string)) { |
| return MaybeHandle<WasmCompiledModule>(); |
| } |
| d.AddAttachedObject(wire_bytes_as_string); |
| |
| Vector<const uint32_t> code_stub_keys = data->CodeStubKeys(); |
| for (int i = 0; i < code_stub_keys.length(); i++) { |
| d.AddAttachedObject( |
| CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked()); |
| } |
| |
| Handle<HeapObject> result; |
| if (!d.Deserialize(isolate).ToHandle(&result)) |
| return MaybeHandle<WasmCompiledModule>(); |
| |
| if (!result->IsFixedArray()) return MaybeHandle<WasmCompiledModule>(); |
| |
| // Cast without type checks, as the module wrapper is not there yet. |
| return handle(static_cast<WasmCompiledModule*>(*result), isolate); |
| } |
| |
| MaybeHandle<HeapObject> ObjectDeserializer::Deserialize(Isolate* isolate) { |
| Initialize(isolate); |
| |
| if (!allocator()->ReserveSpace()) return MaybeHandle<HeapObject>(); |
| |
| DCHECK(deserializing_user_code()); |
| HandleScope scope(isolate); |
| Handle<HeapObject> result; |
| { |
| DisallowHeapAllocation no_gc; |
| Object* root; |
| VisitRootPointer(Root::kPartialSnapshotCache, &root); |
| DeserializeDeferredObjects(); |
| FlushICacheForNewCodeObjectsAndRecordEmbeddedObjects(); |
| result = Handle<HeapObject>(HeapObject::cast(root)); |
| Rehash(); |
| allocator()->RegisterDeserializedObjectsForBlackAllocation(); |
| } |
| CommitPostProcessedObjects(); |
| return scope.CloseAndEscape(result); |
| } |
| |
| void ObjectDeserializer:: |
| 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); |
| Assembler::FlushICache(isolate(), code->instruction_start(), |
| code->instruction_size()); |
| } |
| } |
| |
| void ObjectDeserializer::CommitPostProcessedObjects() { |
| CHECK_LE(new_internalized_strings().size(), kMaxInt); |
| StringTable::EnsureCapacityForDeserialization( |
| isolate(), static_cast<int>(new_internalized_strings().size())); |
| for (Handle<String> string : new_internalized_strings()) { |
| StringTableInsertionKey key(*string); |
| DCHECK_NULL(StringTable::ForwardStringIfExists(isolate(), &key, *string)); |
| StringTable::LookupKey(isolate(), &key); |
| } |
| |
| Heap* heap = isolate()->heap(); |
| Factory* factory = isolate()->factory(); |
| for (Handle<Script> script : new_scripts()) { |
| // Assign a new script id to avoid collision. |
| script->set_id(isolate()->heap()->NextScriptId()); |
| // Add script to list. |
| Handle<Object> list = WeakFixedArray::Add(factory->script_list(), script); |
| heap->SetRootScriptList(*list); |
| } |
| } |
| |
| } // namespace internal |
| } // namespace v8 |