Changeset 291933 in webkit


Ignore:
Timestamp:
Mar 25, 2022 10:26:02 PM (2 years ago)
Author:
Chris Dumez
Message:

Simplify / Optimize JSNodeOwner::isReachableFromOpaqueRoots()
https://bugs.webkit.org/show_bug.cgi?id=238380

Reviewed by Geoffrey Garen.

Drop checks specific to HTMLAudioElement and HTMLImageElement from
JSNodeOwner::isReachableFromOpaqueRoots() so that other Node wrappers
that are not audio or image elements do not have to pay the cost.

In the HTMLAudioElement case, HTMLAudioElement already subclasses HTMLMediaElement which
is an ActiveDOMObject and HTMLMediaElement::virtualHasPendingActivity() already takes
care of keeping the JS wrapper alive is there is audio playing.

For HTMLImageElement, I made it subclass ActiveDOMObject so that the JSHTMLImageElement
wrapper is now calling HTMLImageElement::hasPendingActivity() instead of every JS Node
wrapper via JSNodeOwner::isReachableFromOpaqueRoots().

  • bindings/js/JSNodeCustom.cpp:

(WebCore::isReachableFromDOM):

  • html/HTMLImageElement.cpp:

(WebCore::HTMLImageElement::HTMLImageElement):
(WebCore::HTMLImageElement::create):
(WebCore::HTMLImageElement::createForLegacyFactoryFunction):
(WebCore::HTMLImageElement::activeDOMObjectName const):
(WebCore::HTMLImageElement::virtualHasPendingActivity const):
(WebCore::HTMLImageElement::hasPendingActivity const): Deleted.

  • html/HTMLImageElement.h:
  • html/HTMLImageElement.idl:
  • html/ImageDocument.cpp:

(WebCore::ImageDocumentElement::create):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r291911 r291933  
     12022-03-25  Chris Dumez  <cdumez@apple.com>
     2
     3        Simplify / Optimize JSNodeOwner::isReachableFromOpaqueRoots()
     4        https://bugs.webkit.org/show_bug.cgi?id=238380
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Drop checks specific to HTMLAudioElement and HTMLImageElement from
     9        JSNodeOwner::isReachableFromOpaqueRoots() so that other Node wrappers
     10        that are not audio or image elements do not have to pay the cost.
     11
     12        In the HTMLAudioElement case, HTMLAudioElement already subclasses HTMLMediaElement which
     13        is an ActiveDOMObject and HTMLMediaElement::virtualHasPendingActivity() already takes
     14        care of keeping the JS wrapper alive is there is audio playing.
     15
     16        For HTMLImageElement, I made it subclass ActiveDOMObject so that the JSHTMLImageElement
     17        wrapper is now calling HTMLImageElement::hasPendingActivity() instead of every JS Node
     18        wrapper via JSNodeOwner::isReachableFromOpaqueRoots().
     19
     20        * bindings/js/JSNodeCustom.cpp:
     21        (WebCore::isReachableFromDOM):
     22        * html/HTMLImageElement.cpp:
     23        (WebCore::HTMLImageElement::HTMLImageElement):
     24        (WebCore::HTMLImageElement::create):
     25        (WebCore::HTMLImageElement::createForLegacyFactoryFunction):
     26        (WebCore::HTMLImageElement::activeDOMObjectName const):
     27        (WebCore::HTMLImageElement::virtualHasPendingActivity const):
     28        (WebCore::HTMLImageElement::hasPendingActivity const): Deleted.
     29        * html/HTMLImageElement.h:
     30        * html/HTMLImageElement.idl:
     31        * html/ImageDocument.cpp:
     32        (WebCore::ImageDocumentElement::create):
     33
    1342022-03-25  Nikolaos Mouchtaris  <nmouchtaris@apple.com>
    235
  • trunk/Source/WebCore/bindings/js/JSNodeCustom.cpp

    r287327 r291933  
    3333#include "DocumentFragment.h"
    3434#include "DocumentType.h"
    35 #include "HTMLAudioElement.h"
    36 #include "HTMLCanvasElement.h"
    3735#include "HTMLElement.h"
    38 #include "HTMLFrameElementBase.h"
    39 #include "HTMLImageElement.h"
    40 #include "HTMLLinkElement.h"
    4136#include "HTMLNames.h"
    42 #include "HTMLScriptElement.h"
    43 #include "HTMLStyleElement.h"
    4437#include "JSAttr.h"
    4538#include "JSCDATASection.h"
     
    6558#include "ShadowRoot.h"
    6659#include "GCReachableRef.h"
    67 #include "StyleSheet.h"
    68 #include "StyledElement.h"
    6960#include "Text.h"
    7061
     
    7768{
    7869    if (!node->isConnected()) {
    79         if (is<Element>(*node)) {
    80             auto& element = downcast<Element>(*node);
    81 
    82             // If a wrapper is the last reference to an image element
    83             // that is loading but not in the document, the wrapper is observable
    84             // because it is the only thing keeping the image element alive, and if
    85             // the element is destroyed, its load event will not fire.
    86             // FIXME: The DOM should manage this issue without the help of JavaScript wrappers.
    87             if (is<HTMLImageElement>(element)) {
    88                 if (downcast<HTMLImageElement>(element).hasPendingActivity()) {
    89                     if (UNLIKELY(reason))
    90                         *reason = "Image element with pending activity";
    91                     return true;
    92                 }
    93             }
    94 #if ENABLE(VIDEO)
    95             else if (is<HTMLAudioElement>(element)) {
    96                 if (!downcast<HTMLAudioElement>(element).paused()) {
    97                     if (UNLIKELY(reason))
    98                         *reason = "Audio element which is not paused";
    99                     return true;
    100                 }
    101             }
    102 #endif
    103         }
    104 
    10570        // If a node is firing event listeners, its wrapper is observable because
    10671        // its wrapper is responsible for marking those event listeners.
  • trunk/Source/WebCore/html/HTMLImageElement.cpp

    r287663 r291933  
    7474HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
    7575    : HTMLElement(tagName, document)
     76    , ActiveDOMObject(document)
    7677    , m_imageLoader(makeUnique<HTMLImageLoader>(*this))
    7778    , m_form(nullptr)
     
    8687Ref<HTMLImageElement> HTMLImageElement::create(Document& document)
    8788{
    88     return adoptRef(*new HTMLImageElement(imgTag, document));
     89    auto image = adoptRef(*new HTMLImageElement(imgTag, document));
     90    image->suspendIfNeeded();
     91    return image;
    8992}
    9093
    9194Ref<HTMLImageElement> HTMLImageElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
    9295{
    93     return adoptRef(*new HTMLImageElement(tagName, document, form));
     96    auto image = adoptRef(*new HTMLImageElement(tagName, document, form));
     97    image->suspendIfNeeded();
     98    return image;
    9499}
    95100
     
    109114    if (height)
    110115        image->setHeight(height.value());
     116    image->suspendIfNeeded();
    111117    return image;
    112118}
     
    867873}
    868874
    869 bool HTMLImageElement::hasPendingActivity() const
     875const char* HTMLImageElement::activeDOMObjectName() const
     876{
     877    return "HTMLImageElement";
     878}
     879
     880bool HTMLImageElement::virtualHasPendingActivity() const
    870881{
    871882    return m_imageLoader->hasPendingActivity();
  • trunk/Source/WebCore/html/HTMLImageElement.h

    r287663 r291933  
    2424#pragma once
    2525
     26#include "ActiveDOMObject.h"
    2627#include "DecodingOptions.h"
    2728#include "FormNamedItem.h"
     
    4647enum class RelevantMutation : bool;
    4748
    48 class HTMLImageElement : public HTMLElement, public FormNamedItem {
     49class HTMLImageElement : public HTMLElement, public FormNamedItem, public ActiveDOMObject {
    4950    WTF_MAKE_ISO_ALLOCATED(HTMLImageElement);
    5051    friend class HTMLFormElement;
     
    110111#endif
    111112
    112     bool hasPendingActivity() const;
    113113    WEBCORE_EXPORT size_t pendingDecodePromisesCountForTesting() const;
    114114
     
    166166    void invalidateAttributeMapping();
    167167
     168    // ActiveDOMObject.
     169    const char* activeDOMObjectName() const final;
     170    bool virtualHasPendingActivity() const final;
     171
    168172    void didAttachRenderers() override;
    169173    RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
  • trunk/Source/WebCore/html/HTMLImageElement.idl

    r289117 r291933  
    2121// https://html.spec.whatwg.org/multipage/embedded-content.html#htmlimageelement
    2222[
     23    ActiveDOMObject,
    2324    ExportMacro=WEBCORE_EXPORT,
     25    Exposed=Window,
    2426    JSGenerateToNativeObject,
    25     Exposed=Window,
    2627    LegacyFactoryFunctionCallWith=CurrentDocument,
    2728    LegacyFactoryFunction=Image(optional unsigned long width, optional unsigned long height)
  • trunk/Source/WebCore/html/ImageDocument.cpp

    r288201 r291933  
    117117inline Ref<ImageDocumentElement> ImageDocumentElement::create(ImageDocument& document)
    118118{
    119     return adoptRef(*new ImageDocumentElement(document));
     119    auto image = adoptRef(*new ImageDocumentElement(document));
     120    image->suspendIfNeeded();
     121    return image;
    120122}
    121123
Note: See TracChangeset for help on using the changeset viewer.