Title: [174445] releases/WebKitGTK/webkit-2.6/Source/WebCore
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;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to