- Revision
- 174445
- Author
- carlo...@webkit.org
- Date
- 2014-10-08 06:11:20 -0700 (Wed, 08 Oct 2014)
Log Message
Merge r174040 - HTMLPlugInElement::isUserObservable() is causing layout
https://bugs.webkit.org/show_bug.cgi?id=137156
Reviewed by Ryosuke Niwa.
While profiling the page load of nytimes.com, I noticed that we were
spending ~4-5% of cpu time in HTMLPlugInElement::isUserObservable().
The reason is that the function calls pluginWidget(), which causes a
layout update in HTMLObjectElement::renderWidgetForJSBindings(), to
make sure the plugin is loaded and its renderer is created.
HTMLPlugInElement::isUserObservable() shouldn't need to do a layout.
This patch does the following to address the problem:
- Rename renderWidgetForJSBindings() to renderWidgetLoadingPlugin()
because this function is not always called from the JS Bindings
nowadays. The new name makes it clearer that this will load the
plugin if needed (to make sure the renderer is created, and by
doing a layout).
- Add a PluginLoadingPolicy argument to
HTMLPlugInElement::pluginWidget() to let the caller control if the
plugin should be loaded or not.
- Update the call to pluginWidget() in isUserObservable() so that
we do not attempt to load the plugin (thus not causing a layout).
No new tests, no behavior change.
* WebCore.exp.in:
* WebCore.order:
* html/HTMLAppletElement.cpp:
(WebCore::HTMLAppletElement::renderWidgetLoadingPlugin):
(WebCore::HTMLAppletElement::renderWidgetForJSBindings): Deleted.
* html/HTMLAppletElement.h:
* html/HTMLEmbedElement.cpp:
(WebCore::HTMLEmbedElement::renderWidgetLoadingPlugin):
(WebCore::HTMLEmbedElement::renderWidgetForJSBindings): Deleted.
* html/HTMLEmbedElement.h:
* html/HTMLObjectElement.cpp:
(WebCore::HTMLObjectElement::renderWidgetLoadingPlugin):
(WebCore::HTMLObjectElement::renderWidgetForJSBindings): Deleted.
* html/HTMLObjectElement.h:
* html/HTMLPlugInElement.cpp:
(WebCore::HTMLPlugInElement::pluginWidget):
(WebCore::HTMLPlugInElement::isUserObservable):
* html/HTMLPlugInElement.h:
Modified Paths
Diff
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog (174444 => 174445)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog 2014-10-08 13:06:58 UTC (rev 174444)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog 2014-10-08 13:11:20 UTC (rev 174445)
@@ -1,3 +1,50 @@
+2014-09-27 Chris Dumez <cdu...@apple.com>
+
+ HTMLPlugInElement::isUserObservable() is causing layout
+ https://bugs.webkit.org/show_bug.cgi?id=137156
+
+ Reviewed by Ryosuke Niwa.
+
+ While profiling the page load of nytimes.com, I noticed that we were
+ spending ~4-5% of cpu time in HTMLPlugInElement::isUserObservable().
+ The reason is that the function calls pluginWidget(), which causes a
+ layout update in HTMLObjectElement::renderWidgetForJSBindings(), to
+ make sure the plugin is loaded and its renderer is created.
+
+ HTMLPlugInElement::isUserObservable() shouldn't need to do a layout.
+ This patch does the following to address the problem:
+ - Rename renderWidgetForJSBindings() to renderWidgetLoadingPlugin()
+ because this function is not always called from the JS Bindings
+ nowadays. The new name makes it clearer that this will load the
+ plugin if needed (to make sure the renderer is created, and by
+ doing a layout).
+ - Add a PluginLoadingPolicy argument to
+ HTMLPlugInElement::pluginWidget() to let the caller control if the
+ plugin should be loaded or not.
+ - Update the call to pluginWidget() in isUserObservable() so that
+ we do not attempt to load the plugin (thus not causing a layout).
+
+ No new tests, no behavior change.
+
+ * WebCore.exp.in:
+ * WebCore.order:
+ * html/HTMLAppletElement.cpp:
+ (WebCore::HTMLAppletElement::renderWidgetLoadingPlugin):
+ (WebCore::HTMLAppletElement::renderWidgetForJSBindings): Deleted.
+ * html/HTMLAppletElement.h:
+ * html/HTMLEmbedElement.cpp:
+ (WebCore::HTMLEmbedElement::renderWidgetLoadingPlugin):
+ (WebCore::HTMLEmbedElement::renderWidgetForJSBindings): Deleted.
+ * html/HTMLEmbedElement.h:
+ * html/HTMLObjectElement.cpp:
+ (WebCore::HTMLObjectElement::renderWidgetLoadingPlugin):
+ (WebCore::HTMLObjectElement::renderWidgetForJSBindings): Deleted.
+ * html/HTMLObjectElement.h:
+ * html/HTMLPlugInElement.cpp:
+ (WebCore::HTMLPlugInElement::pluginWidget):
+ (WebCore::HTMLPlugInElement::isUserObservable):
+ * html/HTMLPlugInElement.h:
+
2014-09-26 Brian J. Burg <b...@cs.washington.edu>
StorageTracker::deleteOrigin being called off the main thread (ASSERTs in inspector/test-harness-trivially-works.html test)
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/WebCore.exp.in (174444 => 174445)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/WebCore.exp.in 2014-10-08 13:06:58 UTC (rev 174444)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/WebCore.exp.in 2014-10-08 13:11:20 UTC (rev 174445)
@@ -1784,7 +1784,6 @@
__ZNK7WebCore16VisibleSelection23isContentRichlyEditableEv
__ZNK7WebCore16VisibleSelection5isAllENS_27EditingBoundaryCrossingRuleE
__ZNK7WebCore17HTMLOptionElement4textEv
-__ZNK7WebCore17HTMLPlugInElement12pluginWidgetEv
__ZNK7WebCore17HTMLSelectElement13selectedIndexEv
__ZNK7WebCore17HTMLSelectElement5valueEv
__ZNK7WebCore17HTMLSelectElement9listItemsEv
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/WebCore.order (174444 => 174445)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/WebCore.order 2014-10-08 13:06:58 UTC (rev 174444)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/WebCore.order 2014-10-08 13:11:20 UTC (rev 174445)
@@ -9187,7 +9187,6 @@
__ZN7WebCore37pluginElementCustomGetOwnPropertySlotINS_19JSHTMLObjectElementENS_13JSHTMLElementEEEbPN3JSC9ExecStateENS3_12PropertyNameERNS3_12PropertySlotEPT_
__ZN7WebCore37runtimeObjectCustomGetOwnPropertySlotEPN3JSC9ExecStateENS0_12PropertyNameERNS0_12PropertySlotEPNS_13JSHTMLElementE
__ZN7WebCore18pluginScriptObjectEPN3JSC9ExecStateEPNS_13JSHTMLElementE
-__ZNK7WebCore17HTMLPlugInElement12pluginWidgetEv
__ZNK7WebCore17HTMLObjectElement25renderWidgetForJSBindingsEv
__ZN7WebCore17HTMLPlugInElement11getInstanceEv
__ZN7WebCore28JSHTMLObjectElementPrototype18getOwnPropertySlotEPN3JSC6JSCellEPNS1_9ExecStateENS1_12PropertyNameERNS1_12PropertySlotE
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLAppletElement.cpp (174444 => 174445)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLAppletElement.cpp 2014-10-08 13:06:58 UTC (rev 174444)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLAppletElement.cpp 2014-10-08 13:11:20 UTC (rev 174445)
@@ -83,10 +83,10 @@
return RenderEmbeddedObject::createForApplet(*this, WTF::move(style));
}
-RenderWidget* HTMLAppletElement::renderWidgetForJSBindings() const
+RenderWidget* HTMLAppletElement::renderWidgetLoadingPlugin() const
{
if (!canEmbedJava())
- return 0;
+ return nullptr;
// Needs to load the plugin immediatedly because this function is called
// when _javascript_ code accesses the plugin.
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLAppletElement.h (174444 => 174445)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLAppletElement.h 2014-10-08 13:06:58 UTC (rev 174444)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLAppletElement.h 2014-10-08 13:11:20 UTC (rev 174445)
@@ -39,7 +39,7 @@
virtual bool rendererIsNeeded(const RenderStyle&) override;
virtual RenderPtr<RenderElement> createElementRenderer(PassRef<RenderStyle>) override;
- virtual RenderWidget* renderWidgetForJSBindings() const override;
+ virtual RenderWidget* renderWidgetLoadingPlugin() const override;
virtual void updateWidget(PluginCreationOption) override;
bool canEmbedJava() const;
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLEmbedElement.cpp (174444 => 174445)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLEmbedElement.cpp 2014-10-08 13:06:58 UTC (rev 174444)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLEmbedElement.cpp 2014-10-08 13:11:20 UTC (rev 174445)
@@ -68,7 +68,7 @@
return 0;
}
-RenderWidget* HTMLEmbedElement::renderWidgetForJSBindings() const
+RenderWidget* HTMLEmbedElement::renderWidgetLoadingPlugin() const
{
FrameView* view = document().view();
if (!view || (!view->isInLayout() && !view->isPainting())) {
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLEmbedElement.h (174444 => 174445)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLEmbedElement.h 2014-10-08 13:06:58 UTC (rev 174444)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLEmbedElement.h 2014-10-08 13:11:20 UTC (rev 174445)
@@ -43,7 +43,7 @@
virtual bool isURLAttribute(const Attribute&) const override;
virtual const AtomicString& imageSourceURL() const override;
- virtual RenderWidget* renderWidgetForJSBindings() const override;
+ virtual RenderWidget* renderWidgetLoadingPlugin() const override;
virtual void updateWidget(PluginCreationOption) override;
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLObjectElement.cpp (174444 => 174445)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLObjectElement.cpp 2014-10-08 13:06:58 UTC (rev 174444)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLObjectElement.cpp 2014-10-08 13:11:20 UTC (rev 174445)
@@ -81,7 +81,7 @@
return adoptRef(new HTMLObjectElement(tagName, document, form, createdByParser));
}
-RenderWidget* HTMLObjectElement::renderWidgetForJSBindings() const
+RenderWidget* HTMLObjectElement::renderWidgetLoadingPlugin() const
{
// Needs to load the plugin immediatedly because this function is called
// when _javascript_ code accesses the plugin.
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLObjectElement.h (174444 => 174445)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLObjectElement.h 2014-10-08 13:06:58 UTC (rev 174444)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLObjectElement.h 2014-10-08 13:11:20 UTC (rev 174445)
@@ -70,7 +70,7 @@
virtual bool isURLAttribute(const Attribute&) const override;
virtual const AtomicString& imageSourceURL() const override;
- virtual RenderWidget* renderWidgetForJSBindings() const override;
+ virtual RenderWidget* renderWidgetLoadingPlugin() const override;
virtual void addSubresourceAttributeURLs(ListHashSet<URL>&) const override;
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLPlugInElement.cpp (174444 => 174445)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLPlugInElement.cpp 2014-10-08 13:06:58 UTC (rev 174444)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLPlugInElement.cpp 2014-10-08 13:11:20 UTC (rev 174445)
@@ -158,17 +158,17 @@
return beforeLoadAllowedLoad;
}
-Widget* HTMLPlugInElement::pluginWidget() const
+Widget* HTMLPlugInElement::pluginWidget(PluginLoadingPolicy loadPolicy) const
{
if (m_inBeforeLoadEventHandler) {
// The plug-in hasn't loaded yet, and it makes no sense to try to load if beforeload handler happened to touch the plug-in element.
// That would recursively call beforeload for the same element.
- return 0;
+ return nullptr;
}
- RenderWidget* renderWidget = renderWidgetForJSBindings();
+ RenderWidget* renderWidget = loadPolicy == PluginLoadingPolicy::Load ? renderWidgetLoadingPlugin() : this->renderWidget();
if (!renderWidget)
- return 0;
+ return nullptr;
return renderWidget->widget();
}
@@ -256,7 +256,7 @@
bool HTMLPlugInElement::isUserObservable() const
{
// No widget - can't be anything to see or hear here.
- Widget* widget = pluginWidget();
+ Widget* widget = pluginWidget(PluginLoadingPolicy::DoNotLoad);
if (!widget || !widget->isPluginViewBase())
return false;
Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLPlugInElement.h (174444 => 174445)
--- releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLPlugInElement.h 2014-10-08 13:06:58 UTC (rev 174444)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/html/HTMLPlugInElement.h 2014-10-08 13:11:20 UTC (rev 174445)
@@ -51,7 +51,8 @@
PassRefPtr<JSC::Bindings::Instance> getInstance();
- WEBCORE_EXPORT Widget* pluginWidget() const;
+ enum class PluginLoadingPolicy { DoNotLoad, Load };
+ WEBCORE_EXPORT Widget* pluginWidget(PluginLoadingPolicy = PluginLoadingPolicy::Load) const;
enum DisplayState {
WaitingForSnapshot,
@@ -116,7 +117,8 @@
bool dispatchBeforeLoadEvent(const String& sourceURL); // Not implemented, generates a compile error if subclasses call this by mistake.
- virtual RenderWidget* renderWidgetForJSBindings() const = 0;
+ // This will load the plugin if necessary.
+ virtual RenderWidget* renderWidgetLoadingPlugin() const = 0;
virtual bool supportsFocus() const override;