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/codegen/assembler-inl.h"
8 #include "src/execution/isolate.h"
9 #include "src/heap/heap-inl.h"
10 #include "src/objects/allocation-site-inl.h"
11 #include "src/objects/objects.h"
12 #include "src/objects/slots.h"
13 #include "src/snapshot/code-serializer.h"
14
15 namespace v8 {
16 namespace internal {
17
ObjectDeserializer(Isolate * isolate,const SerializedCodeData * data)18 ObjectDeserializer::ObjectDeserializer(Isolate* isolate,
19 const SerializedCodeData* data)
20 : Deserializer(isolate, data->Payload(), data->GetMagicNumber(), true,
21 false) {}
22
23 MaybeHandle<SharedFunctionInfo>
DeserializeSharedFunctionInfo(Isolate * isolate,const SerializedCodeData * data,Handle<String> source)24 ObjectDeserializer::DeserializeSharedFunctionInfo(
25 Isolate* isolate, const SerializedCodeData* data, Handle<String> source) {
26 ObjectDeserializer d(isolate, data);
27
28 d.AddAttachedObject(source);
29
30 Handle<HeapObject> result;
31 return d.Deserialize().ToHandle(&result)
32 ? Handle<SharedFunctionInfo>::cast(result)
33 : MaybeHandle<SharedFunctionInfo>();
34 }
35
36 MaybeHandle<SharedFunctionInfo>
DeserializeSharedFunctionInfoOffThread(LocalIsolate * isolate,const SerializedCodeData * data,Handle<String> source)37 ObjectDeserializer::DeserializeSharedFunctionInfoOffThread(
38 LocalIsolate* isolate, const SerializedCodeData* data,
39 Handle<String> source) {
40 // TODO(leszeks): Add LocalHeap support to deserializer
41 UNREACHABLE();
42 }
43
Deserialize()44 MaybeHandle<HeapObject> ObjectDeserializer::Deserialize() {
45 DCHECK(deserializing_user_code());
46 HandleScope scope(isolate());
47 Handle<HeapObject> result;
48 {
49 result = ReadObject();
50 DeserializeDeferredObjects();
51 CHECK(new_code_objects().empty());
52 LinkAllocationSites();
53 CHECK(new_maps().empty());
54 WeakenDescriptorArrays();
55 }
56
57 Rehash();
58 CommitPostProcessedObjects();
59 return scope.CloseAndEscape(result);
60 }
61
CommitPostProcessedObjects()62 void ObjectDeserializer::CommitPostProcessedObjects() {
63 for (Handle<JSArrayBuffer> buffer : new_off_heap_array_buffers()) {
64 uint32_t store_index = buffer->GetBackingStoreRefForDeserialization();
65 auto bs = backing_store(store_index);
66 SharedFlag shared =
67 bs && bs->is_shared() ? SharedFlag::kShared : SharedFlag::kNotShared;
68 buffer->Setup(shared, bs);
69 }
70
71 for (Handle<Script> script : new_scripts()) {
72 // Assign a new script id to avoid collision.
73 script->set_id(isolate()->GetNextScriptId());
74 LogScriptEvents(*script);
75 // Add script to list.
76 Handle<WeakArrayList> list = isolate()->factory()->script_list();
77 list = WeakArrayList::AddToEnd(isolate(), list,
78 MaybeObjectHandle::Weak(script));
79 isolate()->heap()->SetRootScriptList(*list);
80 }
81 }
82
LinkAllocationSites()83 void ObjectDeserializer::LinkAllocationSites() {
84 DisallowGarbageCollection no_gc;
85 Heap* heap = isolate()->heap();
86 // Allocation sites are present in the snapshot, and must be linked into
87 // a list at deserialization time.
88 for (Handle<AllocationSite> site : new_allocation_sites()) {
89 if (!site->HasWeakNext()) continue;
90 // TODO(mvstanton): consider treating the heap()->allocation_sites_list()
91 // as a (weak) root. If this root is relocated correctly, this becomes
92 // unnecessary.
93 if (heap->allocation_sites_list() == Smi::zero()) {
94 site->set_weak_next(ReadOnlyRoots(heap).undefined_value());
95 } else {
96 site->set_weak_next(heap->allocation_sites_list());
97 }
98 heap->set_allocation_sites_list(*site);
99 }
100 }
101
102 } // namespace internal
103 } // namespace v8
104