• 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/context-deserializer.h"
6 
7 #include "src/api/api-inl.h"
8 #include "src/common/assert-scope.h"
9 #include "src/heap/heap-inl.h"
10 #include "src/objects/js-array-buffer-inl.h"
11 #include "src/objects/slots.h"
12 #include "src/snapshot/snapshot.h"
13 
14 namespace v8 {
15 namespace internal {
16 
DeserializeContext(Isolate * isolate,const SnapshotData * data,bool can_rehash,Handle<JSGlobalProxy> global_proxy,v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer)17 MaybeHandle<Context> ContextDeserializer::DeserializeContext(
18     Isolate* isolate, const SnapshotData* data, bool can_rehash,
19     Handle<JSGlobalProxy> global_proxy,
20     v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
21   ContextDeserializer d(isolate, data, can_rehash);
22 
23   MaybeHandle<Object> maybe_result =
24       d.Deserialize(isolate, global_proxy, embedder_fields_deserializer);
25 
26   Handle<Object> result;
27   return maybe_result.ToHandle(&result) ? Handle<Context>::cast(result)
28                                         : MaybeHandle<Context>();
29 }
30 
Deserialize(Isolate * isolate,Handle<JSGlobalProxy> global_proxy,v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer)31 MaybeHandle<Object> ContextDeserializer::Deserialize(
32     Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
33     v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
34   // Replace serialized references to the global proxy and its map with the
35   // given global proxy and its map.
36   AddAttachedObject(global_proxy);
37   AddAttachedObject(handle(global_proxy->map(), isolate));
38 
39   Handle<Object> result;
40   {
41     // There's no code deserialized here. If this assert fires then that's
42     // changed and logging should be added to notify the profiler et al. of
43     // the new code, which also has to be flushed from instruction cache.
44     DisallowCodeAllocation no_code_allocation;
45 
46     result = ReadObject();
47     DeserializeDeferredObjects();
48     DeserializeEmbedderFields(embedder_fields_deserializer);
49 
50     LogNewMapEvents();
51     WeakenDescriptorArrays();
52   }
53 
54   if (should_rehash()) Rehash();
55   SetupOffHeapArrayBufferBackingStores();
56 
57   return result;
58 }
59 
SetupOffHeapArrayBufferBackingStores()60 void ContextDeserializer::SetupOffHeapArrayBufferBackingStores() {
61   for (Handle<JSArrayBuffer> buffer : new_off_heap_array_buffers()) {
62     uint32_t store_index = buffer->GetBackingStoreRefForDeserialization();
63     auto bs = backing_store(store_index);
64     SharedFlag shared =
65         bs && bs->is_shared() ? SharedFlag::kShared : SharedFlag::kNotShared;
66     DCHECK_IMPLIES(bs, buffer->is_resizable() == bs->is_resizable());
67     ResizableFlag resizable = bs && bs->is_resizable()
68                                   ? ResizableFlag::kResizable
69                                   : ResizableFlag::kNotResizable;
70     buffer->Setup(shared, resizable, bs);
71   }
72 }
73 
DeserializeEmbedderFields(v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer)74 void ContextDeserializer::DeserializeEmbedderFields(
75     v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
76   if (!source()->HasMore() || source()->Get() != kEmbedderFieldsData) return;
77   DisallowGarbageCollection no_gc;
78   DisallowJavascriptExecution no_js(isolate());
79   DisallowCompilation no_compile(isolate());
80   DCHECK_NOT_NULL(embedder_fields_deserializer.callback);
81   for (int code = source()->Get(); code != kSynchronize;
82        code = source()->Get()) {
83     HandleScope scope(isolate());
84     Handle<JSObject> obj = Handle<JSObject>::cast(GetBackReferencedObject());
85     int index = source()->GetInt();
86     int size = source()->GetInt();
87     // TODO(yangguo,jgruber): Turn this into a reusable shared buffer.
88     byte* data = new byte[size];
89     source()->CopyRaw(data, size);
90     embedder_fields_deserializer.callback(v8::Utils::ToLocal(obj), index,
91                                           {reinterpret_cast<char*>(data), size},
92                                           embedder_fields_deserializer.data);
93     delete[] data;
94   }
95 }
96 }  // namespace internal
97 }  // namespace v8
98