- Revision
- 292342
- Author
- alanc...@apple.com
- Date
- 2022-04-04 14:56:20 -0700 (Mon, 04 Apr 2022)
Log Message
Cherry-pick r291933. rdar://91259284
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):
Modified Paths
Diff
Modified: branches/safari-613-branch/Source/WebCore/bindings/js/JSNodeCustom.cpp (292341 => 292342)
--- branches/safari-613-branch/Source/WebCore/bindings/js/JSNodeCustom.cpp 2022-04-04 21:56:17 UTC (rev 292341)
+++ branches/safari-613-branch/Source/WebCore/bindings/js/JSNodeCustom.cpp 2022-04-04 21:56:20 UTC (rev 292342)
@@ -32,15 +32,8 @@
#include "Document.h"
#include "DocumentFragment.h"
#include "DocumentType.h"
-#include "HTMLAudioElement.h"
-#include "HTMLCanvasElement.h"
#include "HTMLElement.h"
-#include "HTMLFrameElementBase.h"
-#include "HTMLImageElement.h"
-#include "HTMLLinkElement.h"
#include "HTMLNames.h"
-#include "HTMLScriptElement.h"
-#include "HTMLStyleElement.h"
#include "JSAttr.h"
#include "JSCDATASection.h"
#include "JSComment.h"
@@ -64,8 +57,6 @@
#include "SVGElement.h"
#include "ShadowRoot.h"
#include "GCReachableRef.h"
-#include "StyleSheet.h"
-#include "StyledElement.h"
#include "Text.h"
namespace WebCore {
@@ -76,32 +67,6 @@
static inline bool isReachableFromDOM(Node* node, AbstractSlotVisitor& visitor, const char** reason)
{
if (!node->isConnected()) {
- if (is<Element>(*node)) {
- auto& element = downcast<Element>(*node);
-
- // If a wrapper is the last reference to an image element
- // that is loading but not in the document, the wrapper is observable
- // because it is the only thing keeping the image element alive, and if
- // the element is destroyed, its load event will not fire.
- // FIXME: The DOM should manage this issue without the help of _javascript_ wrappers.
- if (is<HTMLImageElement>(element)) {
- if (downcast<HTMLImageElement>(element).hasPendingActivity()) {
- if (UNLIKELY(reason))
- *reason = "Image element with pending activity";
- return true;
- }
- }
-#if ENABLE(VIDEO)
- else if (is<HTMLAudioElement>(element)) {
- if (!downcast<HTMLAudioElement>(element).paused()) {
- if (UNLIKELY(reason))
- *reason = "Audio element which is not paused";
- return true;
- }
- }
-#endif
- }
-
// If a node is firing event listeners, its wrapper is observable because
// its wrapper is responsible for marking those event listeners.
if (node->isFiringEventListeners()) {
Modified: branches/safari-613-branch/Source/WebCore/html/HTMLImageElement.cpp (292341 => 292342)
--- branches/safari-613-branch/Source/WebCore/html/HTMLImageElement.cpp 2022-04-04 21:56:17 UTC (rev 292341)
+++ branches/safari-613-branch/Source/WebCore/html/HTMLImageElement.cpp 2022-04-04 21:56:20 UTC (rev 292342)
@@ -73,6 +73,7 @@
HTMLImageElement::HTMLImageElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
: HTMLElement(tagName, document)
+ , ActiveDOMObject(document)
, m_imageLoader(makeUnique<HTMLImageLoader>(*this))
, m_form(nullptr)
, m_formSetByParser(form)
@@ -85,12 +86,16 @@
Ref<HTMLImageElement> HTMLImageElement::create(Document& document)
{
- return adoptRef(*new HTMLImageElement(imgTag, document));
+ auto image = adoptRef(*new HTMLImageElement(imgTag, document));
+ image->suspendIfNeeded();
+ return image;
}
Ref<HTMLImageElement> HTMLImageElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
{
- return adoptRef(*new HTMLImageElement(tagName, document, form));
+ auto image = adoptRef(*new HTMLImageElement(tagName, document, form));
+ image->suspendIfNeeded();
+ return image;
}
HTMLImageElement::~HTMLImageElement()
@@ -108,6 +113,7 @@
image->setWidth(width.value());
if (height)
image->setHeight(height.value());
+ image->suspendIfNeeded();
return image;
}
@@ -866,8 +872,13 @@
m_imageLoader->setLoadManually(loadManually);
}
-bool HTMLImageElement::hasPendingActivity() const
+const char* HTMLImageElement::activeDOMObjectName() const
{
+ return "HTMLImageElement";
+}
+
+bool HTMLImageElement::virtualHasPendingActivity() const
+{
return m_imageLoader->hasPendingActivity();
}
Modified: branches/safari-613-branch/Source/WebCore/html/HTMLImageElement.h (292341 => 292342)
--- branches/safari-613-branch/Source/WebCore/html/HTMLImageElement.h 2022-04-04 21:56:17 UTC (rev 292341)
+++ branches/safari-613-branch/Source/WebCore/html/HTMLImageElement.h 2022-04-04 21:56:20 UTC (rev 292342)
@@ -23,6 +23,7 @@
#pragma once
+#include "ActiveDOMObject.h"
#include "DecodingOptions.h"
#include "FormNamedItem.h"
#include "GraphicsLayer.h"
@@ -45,7 +46,7 @@
enum class ReferrerPolicy : uint8_t;
enum class RelevantMutation : bool;
-class HTMLImageElement : public HTMLElement, public FormNamedItem {
+class HTMLImageElement : public HTMLElement, public FormNamedItem, public ActiveDOMObject {
WTF_MAKE_ISO_ALLOCATED(HTMLImageElement);
friend class HTMLFormElement;
public:
@@ -109,7 +110,6 @@
const String& attachmentIdentifier() const;
#endif
- bool hasPendingActivity() const;
WEBCORE_EXPORT size_t pendingDecodePromisesCountForTesting() const;
bool canContainRangeEndPoint() const override { return false; }
@@ -165,6 +165,10 @@
void collectExtraStyleForPresentationalHints(MutableStyleProperties&) override;
void invalidateAttributeMapping();
+ // ActiveDOMObject.
+ const char* activeDOMObjectName() const final;
+ bool virtualHasPendingActivity() const final;
+
void didAttachRenderers() override;
RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) override;
void setBestFitURLAndDPRFromImageCandidate(const ImageCandidate&);
Modified: branches/safari-613-branch/Source/WebCore/html/HTMLImageElement.idl (292341 => 292342)
--- branches/safari-613-branch/Source/WebCore/html/HTMLImageElement.idl 2022-04-04 21:56:17 UTC (rev 292341)
+++ branches/safari-613-branch/Source/WebCore/html/HTMLImageElement.idl 2022-04-04 21:56:20 UTC (rev 292342)
@@ -20,9 +20,10 @@
// https://html.spec.whatwg.org/multipage/embedded-content.html#htmlimageelement
[
+ ActiveDOMObject,
ExportMacro=WEBCORE_EXPORT,
+ Exposed=Window,
JSGenerateToNativeObject,
- Exposed=Window,
LegacyFactoryFunctionCallWith=Document,
LegacyFactoryFunction=Image(optional unsigned long width, optional unsigned long height)
] interface HTMLImageElement : HTMLElement {
Modified: branches/safari-613-branch/Source/WebCore/html/ImageDocument.cpp (292341 => 292342)
--- branches/safari-613-branch/Source/WebCore/html/ImageDocument.cpp 2022-04-04 21:56:17 UTC (rev 292341)
+++ branches/safari-613-branch/Source/WebCore/html/ImageDocument.cpp 2022-04-04 21:56:20 UTC (rev 292342)
@@ -116,7 +116,9 @@
inline Ref<ImageDocumentElement> ImageDocumentElement::create(ImageDocument& document)
{
- return adoptRef(*new ImageDocumentElement(document));
+ auto image = adoptRef(*new ImageDocumentElement(document));
+ image->suspendIfNeeded();
+ return image;
}
// --------