• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/heap/local-factory-inl.h"
11 #include "src/objects/allocation-site-inl.h"
12 #include "src/objects/js-array-buffer-inl.h"
13 #include "src/objects/objects.h"
14 #include "src/objects/slots.h"
15 #include "src/snapshot/code-serializer.h"
16 
17 namespace v8 {
18 namespace internal {
19 
ObjectDeserializer(Isolate * isolate,const SerializedCodeData * data)20 ObjectDeserializer::ObjectDeserializer(Isolate* isolate,
21                                        const SerializedCodeData* data)
22     : Deserializer(isolate, data->Payload(), data->GetMagicNumber(), true,
23                    false) {}
24 
25 MaybeHandle<SharedFunctionInfo>
DeserializeSharedFunctionInfo(Isolate * isolate,const SerializedCodeData * data,Handle<String> source)26 ObjectDeserializer::DeserializeSharedFunctionInfo(
27     Isolate* isolate, const SerializedCodeData* data, Handle<String> source) {
28   ObjectDeserializer d(isolate, data);
29 
30   d.AddAttachedObject(source);
31 
32   Handle<HeapObject> result;
33   return d.Deserialize().ToHandle(&result)
34              ? Handle<SharedFunctionInfo>::cast(result)
35              : MaybeHandle<SharedFunctionInfo>();
36 }
37 
Deserialize()38 MaybeHandle<HeapObject> ObjectDeserializer::Deserialize() {
39   DCHECK(deserializing_user_code());
40   HandleScope scope(isolate());
41   Handle<HeapObject> result;
42   {
43     result = ReadObject();
44     DeserializeDeferredObjects();
45     CHECK(new_code_objects().empty());
46     LinkAllocationSites();
47     CHECK(new_maps().empty());
48     WeakenDescriptorArrays();
49   }
50 
51   Rehash();
52   CommitPostProcessedObjects();
53   return scope.CloseAndEscape(result);
54 }
55 
CommitPostProcessedObjects()56 void ObjectDeserializer::CommitPostProcessedObjects() {
57   for (Handle<JSArrayBuffer> buffer : new_off_heap_array_buffers()) {
58     uint32_t store_index = buffer->GetBackingStoreRefForDeserialization();
59     auto bs = backing_store(store_index);
60     SharedFlag shared =
61         bs && bs->is_shared() ? SharedFlag::kShared : SharedFlag::kNotShared;
62     // TODO(v8:11111): Support RAB / GSAB.
63     CHECK(!bs || !bs->is_resizable());
64     buffer->Setup(shared, ResizableFlag::kNotResizable, bs);
65   }
66 
67   for (Handle<Script> script : new_scripts()) {
68     // Assign a new script id to avoid collision.
69     script->set_id(isolate()->GetNextScriptId());
70     LogScriptEvents(*script);
71     // Add script to list.
72     Handle<WeakArrayList> list = isolate()->factory()->script_list();
73     list = WeakArrayList::AddToEnd(isolate(), list,
74                                    MaybeObjectHandle::Weak(script));
75     isolate()->heap()->SetRootScriptList(*list);
76   }
77 }
78 
LinkAllocationSites()79 void ObjectDeserializer::LinkAllocationSites() {
80   DisallowGarbageCollection no_gc;
81   Heap* heap = isolate()->heap();
82   // Allocation sites are present in the snapshot, and must be linked into
83   // a list at deserialization time.
84   for (Handle<AllocationSite> site : new_allocation_sites()) {
85     if (!site->HasWeakNext()) continue;
86     // TODO(mvstanton): consider treating the heap()->allocation_sites_list()
87     // as a (weak) root. If this root is relocated correctly, this becomes
88     // unnecessary.
89     if (heap->allocation_sites_list() == Smi::zero()) {
90       site->set_weak_next(ReadOnlyRoots(heap).undefined_value());
91     } else {
92       site->set_weak_next(heap->allocation_sites_list());
93     }
94     heap->set_allocation_sites_list(*site);
95   }
96 }
97 
OffThreadObjectDeserializer(LocalIsolate * isolate,const SerializedCodeData * data)98 OffThreadObjectDeserializer::OffThreadObjectDeserializer(
99     LocalIsolate* isolate, const SerializedCodeData* data)
100     : Deserializer(isolate, data->Payload(), data->GetMagicNumber(), true,
101                    false) {}
102 
103 MaybeHandle<SharedFunctionInfo>
DeserializeSharedFunctionInfo(LocalIsolate * isolate,const SerializedCodeData * data,std::vector<Handle<Script>> * deserialized_scripts)104 OffThreadObjectDeserializer::DeserializeSharedFunctionInfo(
105     LocalIsolate* isolate, const SerializedCodeData* data,
106     std::vector<Handle<Script>>* deserialized_scripts) {
107   OffThreadObjectDeserializer d(isolate, data);
108 
109   // Attach the empty string as the source.
110   d.AddAttachedObject(isolate->factory()->empty_string());
111 
112   Handle<HeapObject> result;
113   if (!d.Deserialize(deserialized_scripts).ToHandle(&result)) {
114     return MaybeHandle<SharedFunctionInfo>();
115   }
116   return Handle<SharedFunctionInfo>::cast(result);
117 }
118 
Deserialize(std::vector<Handle<Script>> * deserialized_scripts)119 MaybeHandle<HeapObject> OffThreadObjectDeserializer::Deserialize(
120     std::vector<Handle<Script>>* deserialized_scripts) {
121   DCHECK(deserializing_user_code());
122   LocalHandleScope scope(isolate());
123   Handle<HeapObject> result;
124   {
125     result = ReadObject();
126     DeserializeDeferredObjects();
127     CHECK(new_code_objects().empty());
128     CHECK(new_allocation_sites().empty());
129     CHECK(new_maps().empty());
130     WeakenDescriptorArrays();
131   }
132 
133   Rehash();
134   CHECK(new_off_heap_array_buffers().empty());
135 
136   // TODO(leszeks): Figure out a better way of dealing with scripts.
137   CHECK_EQ(new_scripts().size(), 1);
138   for (Handle<Script> script : new_scripts()) {
139     // Assign a new script id to avoid collision.
140     script->set_id(isolate()->GetNextScriptId());
141     LogScriptEvents(*script);
142     deserialized_scripts->push_back(
143         isolate()->heap()->NewPersistentHandle(script));
144   }
145 
146   return scope.CloseAndEscape(result);
147 }
148 
149 }  // namespace internal
150 }  // namespace v8
151