[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
antonm at chromium.org
antonm at chromium.org
Wed Dec 22 13:04:33 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit f49851c9f28cee9717822c70bf6e031b08a1cc76
Author: antonm at chromium.org <antonm at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Sep 6 17:46:44 2010 +0000
2010-09-06 Anton Muhin <antonm at chromium.org>
Reviewed by Adam Barth.
[v8] Inline hot methods for V8 to WebCore and back conversions
https://bugs.webkit.org/show_bug.cgi?id=45270
Inline fast paths of hot functions performing conversions from V8 wrappers
to WebCore native objects and back.
That slightly increases the size of binary (within 0.1% for both Ubuntu
and Windows, but those builds are slightly different from official ones),
but gives performance boost (3--5% on Windows, up to 8% on Ubuntu).
* bindings/scripts/CodeGeneratorV8.pm:
* bindings/v8/V8DOMWindowShell.cpp:
(WebCore::V8DOMWindowShell::initContextIfNeeded):
* bindings/v8/V8DOMWindowShell.h:
* bindings/v8/V8DOMWrapper.cpp:
(WebCore::V8DOMWrapper::getWrapperSlow):
* bindings/v8/V8DOMWrapper.h:
(WebCore::V8DOMWrapper::getWrapper):
* bindings/v8/custom/V8NodeCustom.cpp:
(WebCore::toV8Slow):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@66840 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 53ec82e..0f9c329 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,27 @@
+2010-09-06 Anton Muhin <antonm at chromium.org>
+
+ Reviewed by Adam Barth.
+
+ [v8] Inline hot methods for V8 to WebCore and back conversions
+ https://bugs.webkit.org/show_bug.cgi?id=45270
+
+ Inline fast paths of hot functions performing conversions from V8 wrappers
+ to WebCore native objects and back.
+ That slightly increases the size of binary (within 0.1% for both Ubuntu
+ and Windows, but those builds are slightly different from official ones),
+ but gives performance boost (3--5% on Windows, up to 8% on Ubuntu).
+
+ * bindings/scripts/CodeGeneratorV8.pm:
+ * bindings/v8/V8DOMWindowShell.cpp:
+ (WebCore::V8DOMWindowShell::initContextIfNeeded):
+ * bindings/v8/V8DOMWindowShell.h:
+ * bindings/v8/V8DOMWrapper.cpp:
+ (WebCore::V8DOMWrapper::getWrapperSlow):
+ * bindings/v8/V8DOMWrapper.h:
+ (WebCore::V8DOMWrapper::getWrapper):
+ * bindings/v8/custom/V8NodeCustom.cpp:
+ (WebCore::toV8Slow):
+
2010-09-06 Shane Stephens <shanestephens at google.com>
Reviewed by Dimitri Glazkov.
diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm
index a46c67c..2dcc192 100644
--- a/WebCore/bindings/scripts/CodeGeneratorV8.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm
@@ -233,6 +233,7 @@ sub GenerateHeader
$headerIncludes{"$podType.h"} = 1 if $podType and ($podType ne "double" and $podType ne "float" and $podType ne "RGBA32");
$headerIncludes{"wtf/text/StringHash.h"} = 1;
$headerIncludes{"WrapperTypeInfo.h"} = 1;
+ $headerIncludes{"V8DOMWrapper.h"} = 1;
my $headerClassInclude = GetHeaderClassInclude($implClassName);
$headerIncludes{$headerClassInclude} = 1 if $headerClassInclude ne "";
@@ -253,15 +254,23 @@ sub GenerateHeader
if ($podType) {
$nativeType = "V8SVGPODTypeWrapper<${nativeType} >";
}
+
+ my $domMapFunction = GetDomMapFunction($dataNode, $interfaceName);
my $forceNewObjectParameter = IsDOMNodeType($interfaceName) ? ", bool forceNewObject = false" : "";
+ my $forceNewObjectInput = IsDOMNodeType($interfaceName) ? ", bool forceNewObject" : "";
+ my $forceNewObjectCall = IsDOMNodeType($interfaceName) ? ", forceNewObject" : "";
+
push(@headerContent, <<END);
public:
static bool HasInstance(v8::Handle<v8::Value> value);
static v8::Persistent<v8::FunctionTemplate> GetRawTemplate();
static v8::Persistent<v8::FunctionTemplate> GetTemplate();
- static ${nativeType}* toNative(v8::Handle<v8::Object>);
- static v8::Handle<v8::Object> wrap(${nativeType}*${forceNewObjectParameter});
+ static ${nativeType}* toNative(v8::Handle<v8::Object> object)
+ {
+ return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
+ }
+ inline static v8::Handle<v8::Object> wrap(${nativeType}*${forceNewObjectParameter});
static void derefObject(void*);
static WrapperTypeInfo info;
END
@@ -336,13 +345,72 @@ END
}
push(@headerContent, <<END);
+private:
+ static v8::Handle<v8::Object> wrapSlow(${nativeType}*);
};
+END
+
+ push(@headerContent, <<END);
+
+v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput})
+{
+END
+ if ($domMapFunction) {
+ push(@headerContent, " if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName);
+ my $getWrapper = IsNodeSubType($dataNode) ? "V8DOMWrapper::getWrapper(impl)" : "${domMapFunction}.get(impl)";
+ push(@headerContent, <<END);
+ v8::Handle<v8::Object> wrapper = ${getWrapper};
+ if (!wrapper.IsEmpty())
+ return wrapper;
+END
+ push(@headerContent, " }\n") if IsDOMNodeType($interfaceName);
+ }
+ push(@headerContent, <<END);
+ return ${className}::wrapSlow(impl);
+}
+END
+
+ if (!HasCustomToV8Implementation($dataNode, $interfaceName)) {
+ push(@headerContent, <<END);
+
+inline v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectParameter})
+{
+ if (!impl)
+ return v8::Null();
+ return ${className}::wrap(impl${forceNewObjectCall});
+}
+END
+ } elsif ($interfaceName ne 'Node') {
+ push(@headerContent, <<END);
+
v8::Handle<v8::Value> toV8(${nativeType}*${forceNewObjectParameter});
END
+ } else {
+ push(@headerContent, <<END);
+
+v8::Handle<v8::Value> toV8Slow(Node*, bool);
+
+inline v8::Handle<v8::Value> toV8(Node* impl, bool forceNewObject = false)
+{
+ if (!impl)
+ return v8::Null();
+ if (!forceNewObject) {
+ v8::Handle<v8::Value> wrapper = V8DOMWrapper::getWrapper(impl);
+ if (!wrapper.IsEmpty())
+ return wrapper;
+ }
+ return toV8Slow(impl, forceNewObject);
+}
+END
+ }
+
if (IsRefPtrType($implClassName)) {
push(@headerContent, <<END);
-v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} >${forceNewObjectParameter});
+inline v8::Handle<v8::Value> toV8(PassRefPtr< ${nativeType} > impl${forceNewObjectParameter})
+{
+ return toV8(impl.get()${forceNewObjectCall});
+}
END
}
@@ -2086,11 +2154,6 @@ v8::Persistent<v8::FunctionTemplate> ${className}::GetTemplate()\
return ${className}Cache;
}
-${nativeType}* ${className}::toNative(v8::Handle<v8::Object> object)
-{
- return reinterpret_cast<${nativeType}*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex));
-}
-
bool ${className}::HasInstance(v8::Handle<v8::Value> value)
{
return GetRawTemplate()->HasInstance(value);
@@ -2359,7 +2422,7 @@ sub GenerateToV8Converters
push(@implContent, <<END);
-v8::Handle<v8::Object> ${className}::wrap(${nativeType}* impl${forceNewObjectInput})
+v8::Handle<v8::Object> ${className}::wrapSlow(${nativeType}* impl)
{
v8::Handle<v8::Object> wrapper;
V8Proxy* proxy = 0;
@@ -2369,26 +2432,17 @@ END
push(@implContent, <<END);
if (impl->document()) {
proxy = V8Proxy::retrieve(impl->document()->frame());
- if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl))
- proxy->windowShell()->initContextIfNeeded();
+ if (proxy && static_cast<Node*>(impl->document()) == static_cast<Node*>(impl)) {
+ if (proxy->windowShell()->initContextIfNeeded()) {
+ // initContextIfNeeded may have created a wrapper for the object, retry from the start.
+ return ${className}::wrap(impl);
+ }
+ }
}
END
}
- if ($domMapFunction) {
- push(@implContent, " if (!forceNewObject) {\n") if IsDOMNodeType($interfaceName);
- if (IsNodeSubType($dataNode)) {
- push(@implContent, " wrapper = V8DOMWrapper::getWrapper(impl);\n");
- } else {
- push(@implContent, " wrapper = ${domMapFunction}.get(impl);\n");
- }
- push(@implContent, <<END);
- if (!wrapper.IsEmpty())
- return wrapper;
-END
- push(@implContent, " }\n") if IsDOMNodeType($interfaceName);
- }
if (IsNodeSubType($dataNode)) {
push(@implContent, <<END);
@@ -2445,28 +2499,6 @@ END
return wrapper;
}
END
-
- if (IsRefPtrType($interfaceName)) {
- push(@implContent, <<END);
-
-v8::Handle<v8::Value> toV8(PassRefPtr<${nativeType} > impl${forceNewObjectInput})
-{
- return toV8(impl.get()${forceNewObjectCall});
-}
-END
- }
-
- if (!HasCustomToV8Implementation($dataNode, $interfaceName)) {
- push(@implContent, <<END);
-
-v8::Handle<v8::Value> toV8(${nativeType}* impl${forceNewObjectInput})
-{
- if (!impl)
- return v8::Null();
- return ${className}::wrap(impl${forceNewObjectCall});
-}
-END
- }
}
sub HasCustomToV8Implementation {
diff --git a/WebCore/bindings/v8/V8DOMWindowShell.cpp b/WebCore/bindings/v8/V8DOMWindowShell.cpp
index d747c75..0748cb6 100644
--- a/WebCore/bindings/v8/V8DOMWindowShell.cpp
+++ b/WebCore/bindings/v8/V8DOMWindowShell.cpp
@@ -242,11 +242,11 @@ void V8DOMWindowShell::clearForNavigation()
// the frame. However, a new inner window is created for the new page.
// If there are JS code holds a closure to the old inner window,
// it won't be able to reach the outer window via its global object.
-void V8DOMWindowShell::initContextIfNeeded()
+bool V8DOMWindowShell::initContextIfNeeded()
{
// Bail out if the context has already been initialized.
if (!m_context.IsEmpty())
- return;
+ return false;
// Create a handle scope for all local handles.
v8::HandleScope handleScope;
@@ -273,7 +273,7 @@ void V8DOMWindowShell::initContextIfNeeded()
m_context = createNewContext(m_global, 0);
if (m_context.IsEmpty())
- return;
+ return false;
v8::Local<v8::Context> v8Context = v8::Local<v8::Context>::New(m_context);
v8::Context::Scope contextScope(v8Context);
@@ -284,7 +284,7 @@ void V8DOMWindowShell::initContextIfNeeded()
// Bail out if allocation of the first global objects fails.
if (m_global.IsEmpty()) {
disposeContextHandles();
- return;
+ return false;
}
#ifndef NDEBUG
V8GCController::registerGlobalHandle(PROXY, this, m_global);
@@ -293,12 +293,12 @@ void V8DOMWindowShell::initContextIfNeeded()
if (!installHiddenObjectPrototype(v8Context)) {
disposeContextHandles();
- return;
+ return false;
}
if (!installDOMWindow(v8Context, m_frame->domWindow())) {
disposeContextHandles();
- return;
+ return false;
}
updateDocument();
@@ -310,6 +310,8 @@ void V8DOMWindowShell::initContextIfNeeded()
// FIXME: This is wrong. We should actually do this for the proper world once
// we do isolated worlds the WebCore way.
m_frame->loader()->dispatchDidClearWindowObjectInWorld(0);
+
+ return true;
}
v8::Persistent<v8::Context> V8DOMWindowShell::createNewContext(v8::Handle<v8::Object> global, int extensionGroup)
diff --git a/WebCore/bindings/v8/V8DOMWindowShell.h b/WebCore/bindings/v8/V8DOMWindowShell.h
index 7958bf1..76c27af 100644
--- a/WebCore/bindings/v8/V8DOMWindowShell.h
+++ b/WebCore/bindings/v8/V8DOMWindowShell.h
@@ -69,7 +69,7 @@ public:
void setContext(v8::Handle<v8::Context>);
static bool installDOMWindow(v8::Handle<v8::Context> context, DOMWindow*);
- void initContextIfNeeded();
+ bool initContextIfNeeded();
void updateDocumentWrapper(v8::Handle<v8::Object> wrapper);
void clearForNavigation();
diff --git a/WebCore/bindings/v8/V8DOMWrapper.cpp b/WebCore/bindings/v8/V8DOMWrapper.cpp
index 921f957..7d7efe5 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.cpp
+++ b/WebCore/bindings/v8/V8DOMWrapper.cpp
@@ -329,9 +329,8 @@ bool V8DOMWrapper::isWrapperOfType(v8::Handle<v8::Value> value, WrapperTypeInfo*
return typeInfo == type;
}
-v8::Handle<v8::Object> V8DOMWrapper::getWrapper(Node* node)
+v8::Handle<v8::Object> V8DOMWrapper::getWrapperSlow(Node* node)
{
- ASSERT(WTF::isMainThread());
V8IsolatedContext* context = V8IsolatedContext::getEntered();
if (LIKELY(!context)) {
v8::Persistent<v8::Object>* wrapper = node->wrapper();
@@ -339,7 +338,6 @@ v8::Handle<v8::Object> V8DOMWrapper::getWrapper(Node* node)
return v8::Handle<v8::Object>();
return *wrapper;
}
-
DOMNodeMapping& domNodeMap = context->world()->domDataStore()->domNodeMap();
return domNodeMap.get(node);
}
diff --git a/WebCore/bindings/v8/V8DOMWrapper.h b/WebCore/bindings/v8/V8DOMWrapper.h
index 943cb8a..ed02743 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.h
+++ b/WebCore/bindings/v8/V8DOMWrapper.h
@@ -33,6 +33,7 @@
#include "Document.h"
#include "Event.h"
+#include "IsolatedWorld.h"
#include "Node.h"
#include "NodeFilter.h"
#include "PlatformString.h"
@@ -130,7 +131,19 @@ namespace WebCore {
static v8::Local<v8::Object> instantiateV8Object(V8Proxy* proxy, WrapperTypeInfo*, void* impl);
- static v8::Handle<v8::Object> getWrapper(Node*);
+ static v8::Handle<v8::Object> getWrapper(Node* node)
+ {
+ ASSERT(WTF::isMainThread());
+ if (LIKELY(!IsolatedWorld::count())) {
+ v8::Persistent<v8::Object>* wrapper = node->wrapper();
+ if (wrapper)
+ return *wrapper;
+ }
+ return getWrapperSlow(node);
+ }
+
+ private:
+ static v8::Handle<v8::Object> getWrapperSlow(Node*);
};
}
diff --git a/WebCore/bindings/v8/custom/V8NodeCustom.cpp b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
index 1f0c79b..50b9899 100644
--- a/WebCore/bindings/v8/custom/V8NodeCustom.cpp
+++ b/WebCore/bindings/v8/custom/V8NodeCustom.cpp
@@ -130,7 +130,7 @@ v8::Handle<v8::Value> V8Node::appendChildCallback(const v8::Arguments& args)
return v8::Null();
}
-v8::Handle<v8::Value> toV8(Node* impl, bool forceNewObject)
+v8::Handle<v8::Value> toV8Slow(Node* impl, bool forceNewObject)
{
if (!impl)
return v8::Null();
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list