blob: 5747f705ae57d733694cd636998f51a4a687d78f [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/codegen/assembler-inl.h"
#include "src/execution/isolate.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(Isolate* isolate,
const SerializedCodeData* data)
: Deserializer(isolate, data->Payload(), data->GetMagicNumber(), true,
false) {}
MaybeHandle<SharedFunctionInfo>
ObjectDeserializer::DeserializeSharedFunctionInfo(
Isolate* isolate, const SerializedCodeData* data, Handle<String> source) {
ObjectDeserializer d(isolate, data);
d.AddAttachedObject(source);
Handle<HeapObject> result;
return d.Deserialize().ToHandle(&result)
? Handle<SharedFunctionInfo>::cast(result)
: MaybeHandle<SharedFunctionInfo>();
}
MaybeHandle<SharedFunctionInfo>
ObjectDeserializer::DeserializeSharedFunctionInfoOffThread(
LocalIsolate* isolate, const SerializedCodeData* data,
Handle<String> source) {
// TODO(leszeks): Add LocalHeap support to deserializer
UNREACHABLE();
}
MaybeHandle<HeapObject> ObjectDeserializer::Deserialize() {
DCHECK(deserializing_user_code());
HandleScope scope(isolate());
Handle<HeapObject> result;
{
result = ReadObject();
DeserializeDeferredObjects();
CHECK(new_code_objects().empty());
LinkAllocationSites();
CHECK(new_maps().empty());
WeakenDescriptorArrays();
}
Rehash();
CommitPostProcessedObjects();
return scope.CloseAndEscape(result);
}
void ObjectDeserializer::CommitPostProcessedObjects() {
for (Handle<JSArrayBuffer> 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);
}
for (Handle<Script> script : new_scripts()) {
// Assign a new script id to avoid collision.
script->set_id(isolate()->GetNextScriptId());
LogScriptEvents(*script);
// Add script to list.
Handle<WeakArrayList> list = isolate()->factory()->script_list();
list = WeakArrayList::AddToEnd(isolate(), list,
MaybeObjectHandle::Weak(script));
isolate()->heap()->SetRootScriptList(*list);
}
}
void ObjectDeserializer::LinkAllocationSites() {
DisallowGarbageCollection no_gc;
Heap* heap = isolate()->heap();
// Allocation sites are present in the snapshot, and must be linked into
// a list at deserialization time.
for (Handle<AllocationSite> site : new_allocation_sites()) {
if (!site->HasWeakNext()) continue;
// TODO(mvstanton): consider treating the heap()->allocation_sites_list()
// as a (weak) root. If this root is relocated correctly, this becomes
// unnecessary.
if (heap->allocation_sites_list() == Smi::zero()) {
site->set_weak_next(ReadOnlyRoots(heap).undefined_value());
} else {
site->set_weak_next(heap->allocation_sites_list());
}
heap->set_allocation_sites_list(*site);
}
}
} // namespace internal
} // namespace v8