Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(463)

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/V8SnapshotCreator.cpp

Issue 2841443005: [Bindings] Create and use V8 context snapshots (Closed)
Patch Set: Fix some behaviors Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #include "bindings/core/v8/V8SnapshotCreator.h"
Yuki 2017/05/12 15:20:10 Copyright?
peria 2017/05/30 08:25:42 Done.
2
3 #include <cstring>
4
5 #include "bindings/core/v8/GeneratedCodeHelper.h"
6 #include "bindings/core/v8/V8Document.h"
7 #include "bindings/core/v8/V8HTMLDocument.h"
8 #include "bindings/core/v8/V8Initializer.h"
9 #include "bindings/core/v8/V8Node.h"
10 #include "bindings/core/v8/V8Window.h"
11 #include "platform/bindings/DOMWrapperWorld.h"
12 #include "platform/bindings/V8ObjectConstructor.h"
13 #include "platform/bindings/V8PerIsolateData.h"
14 #include "platform/bindings/V8PrivateProperty.h"
15
16 #include <v8.h>
Yuki 2017/05/12 15:20:10 s|<v8.h>|"v8/include/v8.h"|
peria 2017/05/30 08:25:42 Done.
17
18 namespace blink {
19
20 namespace {
21
22 bool g_taking_snapshot = false;
Yuki 2017/05/15 09:37:29 Put a comment when this is true and what is guaran
peria 2017/05/30 08:25:42 Done.
23
24 // NOTE(peria): This method is almost a copy of
25 // V8PerContext::CreateWrapperFromCacheSlowCase().
26 v8::Local<v8::Function> ConstructPlainType(v8::Isolate* isolate,
Yuki 2017/05/15 09:37:29 Let's merge this code into V8PerContextData::Const
peria 2017/05/30 08:25:42 Acknowledged.
27 const DOMWrapperWorld& world,
28 v8::Local<v8::Context> context,
29 const WrapperTypeInfo* type) {
30 v8::Context::Scope scope(context);
31 // We shouldn't reach this point for the types that are implemented in v8 such
32 // as typed arrays and hence don't have domTemplateFunction.
33 DCHECK(type->dom_template_function);
34 v8::Local<v8::FunctionTemplate> interface_template =
35 type->domTemplate(isolate, world);
36 // Getting the function might fail if we're running out of stack or memory.
37 v8::Local<v8::Function> interface_object;
38 if (!interface_template->GetFunction(context).ToLocal(&interface_object))
39 return v8::Local<v8::Function>();
40
41 if (type->parent_class) {
42 v8::Local<v8::Object> prototype_template =
43 ConstructPlainType(isolate, world, context, type->parent_class);
44 CHECK(interface_object->SetPrototype(context, prototype_template)
45 .ToChecked());
46 }
47
48 v8::Local<v8::Value> prototype_value;
49 CHECK(interface_object->Get(context, V8AtomicString(isolate, "prototype"))
50 .ToLocal(&prototype_value));
51 CHECK(prototype_value->IsObject());
52 v8::Local<v8::Object> prototype_object = prototype_value.As<v8::Object>();
53 if (prototype_object->InternalFieldCount() ==
54 kV8PrototypeInternalFieldcount &&
55 type->wrapper_type_prototype ==
56 WrapperTypeInfo::kWrapperTypeObjectPrototype) {
57 prototype_object->SetAlignedPointerInInternalField(
58 kV8PrototypeTypeIndex, const_cast<WrapperTypeInfo*>(type));
59 }
60 type->PreparePrototypeAndInterfaceObject(
61 context, world, prototype_object, interface_object, interface_template);
62
63 return interface_object;
64 }
65
66 // NOTE(peria): This method is almost a copy of
67 // V8PerContext::CreateWrapperFromCacheSlowCase().
68 v8::Local<v8::Object> CreatePlainWrapper(v8::Isolate* isolate,
Yuki 2017/05/15 09:37:29 Ditto.
peria 2017/05/30 08:25:42 Acknowledged.
69 const DOMWrapperWorld& world,
70 v8::Local<v8::Context> context,
71 const WrapperTypeInfo* type) {
72 CHECK(V8HTMLDocument::wrapperTypeInfo.Equals(type));
73
74 v8::Context::Scope scope(context);
75 v8::Local<v8::Function> interface_object =
76 ConstructPlainType(isolate, world, context, type);
77 CHECK(!interface_object.IsEmpty());
78 v8::Local<v8::Object> instance_template;
79 CHECK(V8ObjectConstructor::NewInstance(isolate, interface_object)
80 .ToLocal(&instance_template));
81 v8::Local<v8::Object> wrapper = instance_template->Clone();
82 wrapper->SetAlignedPointerInInternalField(kV8DOMWrapperTypeIndex,
83 const_cast<WrapperTypeInfo*>(type));
84 return wrapper;
85 }
86
87 } // namespace
88
89 void V8SnapshotCreator::TakeSnapshot(v8::SnapshotCreator* creator,
90 int world_id) {
91 DCHECK(g_taking_snapshot);
92 v8::Isolate* isolate = creator->GetIsolate();
93 CHECK_EQ(isolate, v8::Isolate::GetCurrent());
94
95 RefPtr<DOMWrapperWorld> world_ptr;
96 if (world_id == 0) {
97 world_ptr = &DOMWrapperWorld::MainWorld();
98 } else {
99 world_ptr = DOMWrapperWorld::EnsureIsolatedWorld(isolate, world_id);
100 }
101 const DOMWrapperWorld& world = *world_ptr;
102
103 // Function templates
104 v8::HandleScope handleScope(isolate);
105 v8::Local<v8::FunctionTemplate> event_target_function_template =
Yuki 2017/05/15 09:37:29 nit: We could have an array of WrapperTypeInfo or
peria 2017/05/30 08:25:42 Done.
106 V8EventTarget::domTemplate(isolate, world);
107 CHECK(!event_target_function_template.IsEmpty());
108
109 v8::Local<v8::FunctionTemplate> window_function_template =
110 V8Window::domTemplate(isolate, world);
111 CHECK(!window_function_template.IsEmpty());
112
113 v8::Local<v8::FunctionTemplate> node_function_template =
114 V8Node::domTemplate(isolate, world);
115 CHECK(!node_function_template.IsEmpty());
116
117 v8::Local<v8::FunctionTemplate> document_function_template =
118 V8Document::domTemplate(isolate, world);
119 CHECK(!document_function_template.IsEmpty());
120
121 v8::Local<v8::FunctionTemplate> html_document_function_template =
122 V8HTMLDocument::domTemplate(isolate, world);
123 CHECK(!html_document_function_template.IsEmpty());
124
125 v8::Local<v8::ObjectTemplate> window_template =
126 window_function_template->InstanceTemplate();
127 CHECK(!window_template.IsEmpty());
128
129 v8::Local<v8::Context> context;
130 v8::Local<v8::Object> wrapper;
131 {
132 V8PerIsolateData::UseCounterDisabledScope use_counter_disabled(
133 V8PerIsolateData::From(isolate));
134 context = v8::Context::New(isolate, nullptr, window_template);
135 }
136 CHECK(!context.IsEmpty());
137
138 if (world.IsMainWorld()) {
139 context->Enter();
140 v8::Context::Scope scope(context);
141 wrapper = CreatePlainWrapper(isolate, world, context,
142 &V8HTMLDocument::wrapperTypeInfo);
143 CHECK(!wrapper.IsEmpty());
144 int indices[] = {kV8DOMWrapperObjectIndex, kV8DOMWrapperTypeIndex};
145 void* values[] = {nullptr, const_cast<WrapperTypeInfo*>(
146 &V8HTMLDocument::wrapperTypeInfo)};
147 wrapper->SetAlignedPointerInInternalFields(WTF_ARRAY_LENGTH(indices),
148 indices, values);
149
150 V8PrivateProperty::Symbol symbol =
151 V8PrivateProperty::GetWindowDocumentCachedAccessor(isolate);
152 CHECK(V8CallBoolean(
153 context->Global()->SetPrivate(context, symbol.GetPrivate(), wrapper)));
154 context->Exit();
155 }
156
157 creator->AddTemplate(event_target_function_template);
158 creator->AddTemplate(window_function_template);
159 creator->AddTemplate(node_function_template);
160 creator->AddTemplate(document_function_template);
161 creator->AddTemplate(html_document_function_template);
162 creator->AddContext(context, Serialize);
163
164 V8PerIsolateData::From(isolate)->ClearAll();
165 isolate->RemoveMessageListeners(V8Initializer::MessageHandlerInMainThread);
Yuki 2017/05/15 09:37:29 Please comment why we need to remove message liste
peria 2017/05/30 08:25:42 Done.
166 }
167
168 v8::StartupData V8SnapshotCreator::SetUpSnapshotCreator(
169 v8::SnapshotCreator* creator) {
170 v8::Isolate* isolate = creator->GetIsolate();
171 CHECK_EQ(isolate, v8::Isolate::GetCurrent());
172
173 // Disable all runtime enabled featuers
174 RuntimeEnabledFeatures::setStableFeaturesEnabled(false);
175 RuntimeEnabledFeatures::setExperimentalFeaturesEnabled(false);
176 RuntimeEnabledFeatures::setTestFeaturesEnabled(false);
Yuki 2017/05/15 09:37:29 Is there any good way to confirm that we've not ye
Yuki 2017/05/15 09:37:29 nit: We might want to define RuntimeEnabledFeature
peria 2017/05/30 08:25:42 Acknowledged.
peria 2017/06/20 10:20:13 Acknowledged.
177
178 {
179 v8::HandleScope handleScope(isolate);
180 creator->SetDefaultContext(v8::Context::New(isolate));
181
182 TakeSnapshot(creator, 0); // main world
183 TakeSnapshot(creator, 1); // non main world
Yuki 2017/05/15 09:37:29 I'm not happy with use of the magic numbers. Shal
peria 2017/05/30 08:25:42 Done.
184 }
185
186 return creator->CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
187 }
188
189 v8::SnapshotCreator* V8SnapshotCreator::GetSnapshotCreator() {
190 DCHECK(g_taking_snapshot);
Yuki 2017/05/15 09:37:29 Add a DCHECK to confirm that it's the main thread.
peria 2017/05/30 08:25:42 Acknowledged.
191 return V8PerIsolateData::From(V8PerIsolateData::MainThreadIsolate())
192 ->GetSnapshotCreator();
193 }
194
195 bool V8SnapshotCreator::TakingSnapshot() {
196 return g_taking_snapshot;
Yuki 2017/05/15 09:37:29 Add a DCHECK to confirm that it's the main thread.
peria 2017/05/30 08:25:42 Acknowledged.
197 }
198
199 void V8SnapshotCreator::SetTakingSnapshot(bool value) {
200 g_taking_snapshot = value;
201 }
202
203 v8::StartupData V8SnapshotCreator::Serialize(v8::Local<v8::Object> holder,
Yuki 2017/05/15 09:37:29 s/Serialize/Serialize(An)InternalField/ Let's make
peria 2017/05/30 08:25:42 Done.
204 int index,
205 void* /*data*/) {
206 FieldType field_type = kNone;
207 const WrapperTypeInfo* wrapper_type = ToWrapperTypeInfo(holder);
208 if (blink::V8HTMLDocument::wrapperTypeInfo.Equals(wrapper_type)) {
209 if (kV8DOMWrapperObjectIndex == index) {
210 field_type = kHTMLDocumentObject;
211 } else if (kV8DOMWrapperTypeIndex == index) {
212 field_type = kHTMLDocumentType;
213 }
214 } else if (blink::V8Document::wrapperTypeInfo.Equals(wrapper_type) &&
215 kV8DOMWrapperTypeIndex == index) {
216 field_type = kDocumentType;
217 } else if (blink::V8Node::wrapperTypeInfo.Equals(wrapper_type) &&
218 kV8DOMWrapperTypeIndex == index) {
219 field_type = kNodeType;
220 }
221
222 // To confirm covering all patterns to be serialized.
223 CHECK_NE(field_type, kNone);
224
225 int size = sizeof(FieldType);
226 char* data = new char[size];
227 std::memcpy(data, &field_type, size);
228
229 return {data, size};
230 }
231
232 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698