blob: 3f92e7757fba990e4e064cb3eeaadf1168b05dfc [file] [log] [blame]
// 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