v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
context-deserializer.cc
Go to the documentation of this file.
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
6
7#include "src/api/api-inl.h"
8#include "src/base/logging.h"
12
13namespace v8 {
14namespace internal {
15
16// static
18 Isolate* isolate, const SnapshotData* data, size_t context_index,
19 bool can_rehash, DirectHandle<JSGlobalProxy> global_proxy,
20 DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
21 TRACE_EVENT0("v8", "V8.DeserializeContext");
22 RCS_SCOPE(isolate, RuntimeCallCounterId::kDeserializeContext);
24 if (V8_UNLIKELY(v8_flags.profile_deserialization)) timer.Start();
25 NestedTimedHistogramScope histogram_timer(
26 isolate->counters()->snapshot_deserialize_context());
27
28 ContextDeserializer d(isolate, data, can_rehash);
29 MaybeDirectHandle<Object> maybe_result =
30 d.Deserialize(isolate, global_proxy, embedder_fields_deserializer);
31
32 if (V8_UNLIKELY(v8_flags.profile_deserialization)) {
33 // ATTENTION: The Memory.json benchmark greps for this exact output. Do not
34 // change it without also updating Memory.json.
35 const int bytes = static_cast<int>(data->RawData().size());
36 const double ms = timer.Elapsed().InMillisecondsF();
37 PrintF("[Deserializing context #%zu (%d bytes) took %0.3f ms]\n",
38 context_index, bytes, ms);
39 }
40
42 if (!maybe_result.ToHandle(&result)) return {};
43
44 return Cast<Context>(result);
45}
46
48 Isolate* isolate, DirectHandle<JSGlobalProxy> global_proxy,
49 DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
50 // Replace serialized references to the global proxy and its map with the
51 // given global proxy and its map.
52 AddAttachedObject(global_proxy);
53 AddAttachedObject(direct_handle(global_proxy->map(), isolate));
54
56 {
57 // There's no code deserialized here. If this assert fires then that's
58 // changed and logging should be added to notify the profiler et al. of
59 // the new code, which also has to be flushed from instruction cache.
60 DisallowCodeAllocation no_code_allocation;
61
63 DCHECK(IsNativeContext(*result));
66 embedder_fields_deserializer);
68 embedder_fields_deserializer.api_wrapper_callback);
71 }
72
73 if (should_rehash()) Rehash();
74
75 return result;
76}
77
78template <typename T>
80 public:
81 T* data() { return data_.get(); }
82
83 void EnsureCapacity(size_t new_capacity) {
84 if (new_capacity > capacity_) {
85 data_.reset(new T[new_capacity]);
86 capacity_ = new_capacity;
87 }
88 }
89
90 private:
91 std::unique_ptr<T[]> data_;
92 size_t capacity_{0};
93};
94
97 DeserializeEmbedderFieldsCallback embedder_fields_deserializer) {
98 if (!source()->HasMore() || source()->Peek() != kEmbedderFieldsData) {
99 return;
100 }
101 // Consume `kEmbedderFieldsData`.
102 source()->Get();
104 DisallowJavascriptExecution no_js(isolate());
105 DisallowCompilation no_compile(isolate());
106 // Buffer is reused across various deserializations. We always copy N bytes
107 // into the backing and pass that N bytes to the embedder via StartupData.
108 PlainBuffer<char> buffer;
109 for (int code = source()->Get(); code != kSynchronize;
110 code = source()->Get()) {
111 HandleScope scope(isolate());
112 DirectHandle<HeapObject> heap_object =
114 const int index = source()->GetUint30();
115 const int size = source()->GetUint30();
116 buffer.EnsureCapacity(size);
117 source()->CopyRaw(buffer.data(), size);
118 if (IsJSObject(*heap_object)) {
119 DirectHandle<JSObject> obj = Cast<JSObject>(heap_object);
121 embedder_fields_deserializer.js_object_callback;
122 DCHECK_NOT_NULL(callback.callback);
123 callback.callback(v8::Utils::ToLocal(obj), index, {buffer.data(), size},
124 callback.data);
125 } else {
126 DCHECK(IsEmbedderDataArray(*heap_object));
128 embedder_fields_deserializer.context_callback;
129 DCHECK_NOT_NULL(callback.callback);
130 callback.callback(v8::Utils::ToLocal(context), index,
131 {buffer.data(), size}, callback.data);
132 }
133 }
134}
135
137 const v8::DeserializeAPIWrapperCallback& api_wrapper_callback) {
138 if (!source()->HasMore() || source()->Peek() != kApiWrapperFieldsData) {
139 return;
140 }
141 // Consume `kApiWrapperFieldsData`.
142 source()->Get();
144 DisallowJavascriptExecution no_js(isolate());
145 DisallowCompilation no_compile(isolate());
146 // Buffer is reused across various deserializations. We always copy N bytes
147 // into the backing and pass that N bytes to the embedder via StartupData.
148 PlainBuffer<char> buffer;
149 // The block for `kApiWrapperFieldsData` consists of consecutive `kNewObject`
150 // blocks that are in the end terminated with a `kSynchronize`.
151 for (int code = source()->Get(); code != kSynchronize;
152 code = source()->Get()) {
153 HandleScope scope(isolate());
154 DirectHandle<JSObject> js_object =
156 const int size = source()->GetUint30();
157 buffer.EnsureCapacity(size);
158 source()->CopyRaw(buffer.data(), size);
159 DCHECK_NOT_NULL(api_wrapper_callback.callback);
160 api_wrapper_callback.callback(v8::Utils::ToLocal(js_object),
161 {buffer.data(), size},
162 api_wrapper_callback.data);
163 }
164}
165
166} // namespace internal
167} // namespace v8
void DeserializeApiWrapperFields(const v8::DeserializeAPIWrapperCallback &api_wrapper_callback)
MaybeDirectHandle< Object > Deserialize(Isolate *isolate, DirectHandle< JSGlobalProxy > global_proxy, DeserializeEmbedderFieldsCallback embedder_fields_deserializer)
static MaybeDirectHandle< Context > DeserializeContext(Isolate *isolate, const SnapshotData *data, size_t context_index, bool can_rehash, DirectHandle< JSGlobalProxy > global_proxy, DeserializeEmbedderFieldsCallback embedder_fields_deserializer)
void DeserializeEmbedderFields(DirectHandle< NativeContext > context, DeserializeEmbedderFieldsCallback embedder_fields_deserializer)
DirectHandle< HeapObject > ReadObject()
void AddAttachedObject(DirectHandle< HeapObject > attached_object)
Handle< HeapObject > GetBackReferencedObject()
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(DirectHandle< S > *out) const
void EnsureCapacity(size_t new_capacity)
void CopyRaw(void *to, int number_of_bytes)
TNode< Object > callback
ZoneVector< RpoNumber > & result
V8_INLINE const Operation & Get(const Graph &graph, OpIndex index)
Definition graph.h:1231
void PrintF(const char *format,...)
Definition utils.cc:39
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
V8_EXPORT_PRIVATE FlagValues v8_flags
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
#define RCS_SCOPE(...)
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK(condition)
Definition logging.h:482
v8::DeserializeInternalFieldsCallback js_object_callback
#define TRACE_EVENT0(category_group, name)
#define V8_UNLIKELY(condition)
Definition v8config.h:660