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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/bindings/core/v8/V8SnapshotCreator.cpp
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8SnapshotCreator.cpp b/third_party/WebKit/Source/bindings/core/v8/V8SnapshotCreator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3f1b7845170361b09ece6ff7972048cf7c38bf6a
--- /dev/null
+++ b/third_party/WebKit/Source/bindings/core/v8/V8SnapshotCreator.cpp
@@ -0,0 +1,232 @@
+#include "bindings/core/v8/V8SnapshotCreator.h"
Yuki 2017/05/12 15:20:10 Copyright?
peria 2017/05/30 08:25:42 Done.
+
+#include <cstring>
+
+#include "bindings/core/v8/GeneratedCodeHelper.h"
+#include "bindings/core/v8/V8Document.h"
+#include "bindings/core/v8/V8HTMLDocument.h"
+#include "bindings/core/v8/V8Initializer.h"
+#include "bindings/core/v8/V8Node.h"
+#include "bindings/core/v8/V8Window.h"
+#include "platform/bindings/DOMWrapperWorld.h"
+#include "platform/bindings/V8ObjectConstructor.h"
+#include "platform/bindings/V8PerIsolateData.h"
+#include "platform/bindings/V8PrivateProperty.h"
+
+#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.
+
+namespace blink {
+
+namespace {
+
+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.
+
+// NOTE(peria): This method is almost a copy of
+// V8PerContext::CreateWrapperFromCacheSlowCase().
+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.
+ const DOMWrapperWorld& world,
+ v8::Local<v8::Context> context,
+ const WrapperTypeInfo* type) {
+ v8::Context::Scope scope(context);
+ // We shouldn't reach this point for the types that are implemented in v8 such
+ // as typed arrays and hence don't have domTemplateFunction.
+ DCHECK(type->dom_template_function);
+ v8::Local<v8::FunctionTemplate> interface_template =
+ type->domTemplate(isolate, world);
+ // Getting the function might fail if we're running out of stack or memory.
+ v8::Local<v8::Function> interface_object;
+ if (!interface_template->GetFunction(context).ToLocal(&interface_object))
+ return v8::Local<v8::Function>();
+
+ if (type->parent_class) {
+ v8::Local<v8::Object> prototype_template =
+ ConstructPlainType(isolate, world, context, type->parent_class);
+ CHECK(interface_object->SetPrototype(context, prototype_template)
+ .ToChecked());
+ }
+
+ v8::Local<v8::Value> prototype_value;
+ CHECK(interface_object->Get(context, V8AtomicString(isolate, "prototype"))
+ .ToLocal(&prototype_value));
+ CHECK(prototype_value->IsObject());
+ v8::Local<v8::Object> prototype_object = prototype_value.As<v8::Object>();
+ if (prototype_object->InternalFieldCount() ==
+ kV8PrototypeInternalFieldcount &&
+ type->wrapper_type_prototype ==
+ WrapperTypeInfo::kWrapperTypeObjectPrototype) {
+ prototype_object->SetAlignedPointerInInternalField(
+ kV8PrototypeTypeIndex, const_cast<WrapperTypeInfo*>(type));
+ }
+ type->PreparePrototypeAndInterfaceObject(
+ context, world, prototype_object, interface_object, interface_template);
+
+ return interface_object;
+}
+
+// NOTE(peria): This method is almost a copy of
+// V8PerContext::CreateWrapperFromCacheSlowCase().
+v8::Local<v8::Object> CreatePlainWrapper(v8::Isolate* isolate,
Yuki 2017/05/15 09:37:29 Ditto.
peria 2017/05/30 08:25:42 Acknowledged.
+ const DOMWrapperWorld& world,
+ v8::Local<v8::Context> context,
+ const WrapperTypeInfo* type) {
+ CHECK(V8HTMLDocument::wrapperTypeInfo.Equals(type));
+
+ v8::Context::Scope scope(context);
+ v8::Local<v8::Function> interface_object =
+ ConstructPlainType(isolate, world, context, type);
+ CHECK(!interface_object.IsEmpty());
+ v8::Local<v8::Object> instance_template;
+ CHECK(V8ObjectConstructor::NewInstance(isolate, interface_object)
+ .ToLocal(&instance_template));
+ v8::Local<v8::Object> wrapper = instance_template->Clone();
+ wrapper->SetAlignedPointerInInternalField(kV8DOMWrapperTypeIndex,
+ const_cast<WrapperTypeInfo*>(type));
+ return wrapper;
+}
+
+} // namespace
+
+void V8SnapshotCreator::TakeSnapshot(v8::SnapshotCreator* creator,
+ int world_id) {
+ DCHECK(g_taking_snapshot);
+ v8::Isolate* isolate = creator->GetIsolate();
+ CHECK_EQ(isolate, v8::Isolate::GetCurrent());
+
+ RefPtr<DOMWrapperWorld> world_ptr;
+ if (world_id == 0) {
+ world_ptr = &DOMWrapperWorld::MainWorld();
+ } else {
+ world_ptr = DOMWrapperWorld::EnsureIsolatedWorld(isolate, world_id);
+ }
+ const DOMWrapperWorld& world = *world_ptr;
+
+ // Function templates
+ v8::HandleScope handleScope(isolate);
+ 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.
+ V8EventTarget::domTemplate(isolate, world);
+ CHECK(!event_target_function_template.IsEmpty());
+
+ v8::Local<v8::FunctionTemplate> window_function_template =
+ V8Window::domTemplate(isolate, world);
+ CHECK(!window_function_template.IsEmpty());
+
+ v8::Local<v8::FunctionTemplate> node_function_template =
+ V8Node::domTemplate(isolate, world);
+ CHECK(!node_function_template.IsEmpty());
+
+ v8::Local<v8::FunctionTemplate> document_function_template =
+ V8Document::domTemplate(isolate, world);
+ CHECK(!document_function_template.IsEmpty());
+
+ v8::Local<v8::FunctionTemplate> html_document_function_template =
+ V8HTMLDocument::domTemplate(isolate, world);
+ CHECK(!html_document_function_template.IsEmpty());
+
+ v8::Local<v8::ObjectTemplate> window_template =
+ window_function_template->InstanceTemplate();
+ CHECK(!window_template.IsEmpty());
+
+ v8::Local<v8::Context> context;
+ v8::Local<v8::Object> wrapper;
+ {
+ V8PerIsolateData::UseCounterDisabledScope use_counter_disabled(
+ V8PerIsolateData::From(isolate));
+ context = v8::Context::New(isolate, nullptr, window_template);
+ }
+ CHECK(!context.IsEmpty());
+
+ if (world.IsMainWorld()) {
+ context->Enter();
+ v8::Context::Scope scope(context);
+ wrapper = CreatePlainWrapper(isolate, world, context,
+ &V8HTMLDocument::wrapperTypeInfo);
+ CHECK(!wrapper.IsEmpty());
+ int indices[] = {kV8DOMWrapperObjectIndex, kV8DOMWrapperTypeIndex};
+ void* values[] = {nullptr, const_cast<WrapperTypeInfo*>(
+ &V8HTMLDocument::wrapperTypeInfo)};
+ wrapper->SetAlignedPointerInInternalFields(WTF_ARRAY_LENGTH(indices),
+ indices, values);
+
+ V8PrivateProperty::Symbol symbol =
+ V8PrivateProperty::GetWindowDocumentCachedAccessor(isolate);
+ CHECK(V8CallBoolean(
+ context->Global()->SetPrivate(context, symbol.GetPrivate(), wrapper)));
+ context->Exit();
+ }
+
+ creator->AddTemplate(event_target_function_template);
+ creator->AddTemplate(window_function_template);
+ creator->AddTemplate(node_function_template);
+ creator->AddTemplate(document_function_template);
+ creator->AddTemplate(html_document_function_template);
+ creator->AddContext(context, Serialize);
+
+ V8PerIsolateData::From(isolate)->ClearAll();
+ 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.
+}
+
+v8::StartupData V8SnapshotCreator::SetUpSnapshotCreator(
+ v8::SnapshotCreator* creator) {
+ v8::Isolate* isolate = creator->GetIsolate();
+ CHECK_EQ(isolate, v8::Isolate::GetCurrent());
+
+ // Disable all runtime enabled featuers
+ RuntimeEnabledFeatures::setStableFeaturesEnabled(false);
+ RuntimeEnabledFeatures::setExperimentalFeaturesEnabled(false);
+ 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.
+
+ {
+ v8::HandleScope handleScope(isolate);
+ creator->SetDefaultContext(v8::Context::New(isolate));
+
+ TakeSnapshot(creator, 0); // main world
+ 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.
+ }
+
+ return creator->CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear);
+}
+
+v8::SnapshotCreator* V8SnapshotCreator::GetSnapshotCreator() {
+ 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.
+ return V8PerIsolateData::From(V8PerIsolateData::MainThreadIsolate())
+ ->GetSnapshotCreator();
+}
+
+bool V8SnapshotCreator::TakingSnapshot() {
+ 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.
+}
+
+void V8SnapshotCreator::SetTakingSnapshot(bool value) {
+ g_taking_snapshot = value;
+}
+
+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.
+ int index,
+ void* /*data*/) {
+ FieldType field_type = kNone;
+ const WrapperTypeInfo* wrapper_type = ToWrapperTypeInfo(holder);
+ if (blink::V8HTMLDocument::wrapperTypeInfo.Equals(wrapper_type)) {
+ if (kV8DOMWrapperObjectIndex == index) {
+ field_type = kHTMLDocumentObject;
+ } else if (kV8DOMWrapperTypeIndex == index) {
+ field_type = kHTMLDocumentType;
+ }
+ } else if (blink::V8Document::wrapperTypeInfo.Equals(wrapper_type) &&
+ kV8DOMWrapperTypeIndex == index) {
+ field_type = kDocumentType;
+ } else if (blink::V8Node::wrapperTypeInfo.Equals(wrapper_type) &&
+ kV8DOMWrapperTypeIndex == index) {
+ field_type = kNodeType;
+ }
+
+ // To confirm covering all patterns to be serialized.
+ CHECK_NE(field_type, kNone);
+
+ int size = sizeof(FieldType);
+ char* data = new char[size];
+ std::memcpy(data, &field_type, size);
+
+ return {data, size};
+}
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698