OLD | NEW |
---|---|
(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 | |
OLD | NEW |