⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 269141 in webkit


Ignore:
Timestamp:
Oct 29, 2020, 1:15:18 AM (6 years ago)
Author:
cathiechen
Message:

Source/WebCore:
IntersectionObserverCallback leaks
https://bugs.webkit.org/show_bug.cgi?id=218225

Reviewed by Ryosuke Niwa.

Unless the page is unloaded, JSIntersectionObserverCallback and objects inside it can not be garbage collected properly.
To fix this, make IntersectionObserverCallback as a weak callback. To keep it alive, in JSIntersectionObserver::visitAdditionalChildren
add the callback to visitor.

Test: intersection-observer/intersection-observer-callback-leak.html

  • Sources.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • bindings/js/JSIntersectionObserverCustom.cpp: Copied from Source/WebCore/page/IntersectionObserverCallback.idl.

(WebCore::JSIntersectionObserver::visitAdditionalChildren):

  • page/IntersectionObserver.h:

(WebCore::IntersectionObserver::callbackConcurrently):

  • page/IntersectionObserver.idl:
  • page/IntersectionObserverCallback.h:

(WebCore::IntersectionObserverCallback::hasCallback const):

  • page/IntersectionObserverCallback.idl:

LayoutTests:
IntersectionObserverCallback leak
https://bugs.webkit.org/show_bug.cgi?id=218225

Reviewed by Ryosuke Niwa.

In intersection-observer-callback-after-gc.html, the callbacks with observed targets deleted should stay alive as long as observers are alive.
In intersection-observer-callback-leak.html, use internals.numberOfLiveNodes to check that the objects inside JSIntersectionObserverCallback
can be garbage collected.

  • intersection-observer/intersection-observer-callback-after-gc-expected.txt: Added.
  • intersection-observer/intersection-observer-callback-after-gc.html: Added.
  • intersection-observer/intersection-observer-callback-leak-expected.txt: Added.
  • intersection-observer/intersection-observer-callback-leak.html: Added.
Location:
trunk
Files:
4 added
8 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r269137 r269141  
     12020-10-29  Cathie Chen  <cathiechen@igalia.com>
     2
     3        IntersectionObserverCallback leak
     4        https://bugs.webkit.org/show_bug.cgi?id=218225
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        In intersection-observer-callback-after-gc.html, the callbacks with observed targets deleted should stay alive as long as observers are alive.
     9        In intersection-observer-callback-leak.html, use `internals.numberOfLiveNodes` to check that the objects inside JSIntersectionObserverCallback
     10        can be garbage collected.
     11
     12        * intersection-observer/intersection-observer-callback-after-gc-expected.txt: Added.
     13        * intersection-observer/intersection-observer-callback-after-gc.html: Added.
     14        * intersection-observer/intersection-observer-callback-leak-expected.txt: Added.
     15        * intersection-observer/intersection-observer-callback-leak.html: Added.
     16
    1172020-10-28  Julian Gonzalez  <julian_a_gonzalez@apple.com>
    218
  • trunk/Source/WebCore/ChangeLog

    r269137 r269141  
     12020-10-29  Cathie Chen  <cathiechen@igalia.com>
     2
     3        IntersectionObserverCallback leaks
     4        https://bugs.webkit.org/show_bug.cgi?id=218225
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Unless the page is unloaded, JSIntersectionObserverCallback and objects inside it can not be garbage collected properly.
     9        To fix this, make IntersectionObserverCallback as a weak callback. To keep it alive, in JSIntersectionObserver::visitAdditionalChildren
     10        add the callback to visitor.
     11
     12        Test: intersection-observer/intersection-observer-callback-leak.html
     13
     14        * Sources.txt:
     15        * WebCore.xcodeproj/project.pbxproj:
     16        * bindings/js/JSIntersectionObserverCustom.cpp: Copied from Source/WebCore/page/IntersectionObserverCallback.idl.
     17        (WebCore::JSIntersectionObserver::visitAdditionalChildren):
     18        * page/IntersectionObserver.h:
     19        (WebCore::IntersectionObserver::callbackConcurrently):
     20        * page/IntersectionObserver.idl:
     21        * page/IntersectionObserverCallback.h:
     22        (WebCore::IntersectionObserverCallback::hasCallback const):
     23        * page/IntersectionObserverCallback.idl:
     24
    1252020-10-28  Julian Gonzalez  <julian_a_gonzalez@apple.com>
    226
  • trunk/Source/WebCore/Sources.txt

    r269081 r269141  
    546546bindings/js/JSIDBSerializationGlobalObject.cpp
    547547bindings/js/JSImageDataCustom.cpp
     548bindings/js/JSIntersectionObserverCustom.cpp
    548549bindings/js/JSIntersectionObserverEntryCustom.cpp
    549550bindings/js/JSLazyEventListener.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r269081 r269141  
    1001310013                77AAD6831ECFB66200BFA2D1 /* CredentialCreationOptions.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CredentialCreationOptions.idl; sourceTree = "<group>"; };
    1001410014                77AAD6851ECFBD3900BFA2D1 /* CredentialCreationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CredentialCreationOptions.h; sourceTree = "<group>"; };
     10015                5868C7D52546E0B300BF9DF3 /* JSIntersectionObserverCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIntersectionObserverCustom.cpp; sourceTree = "<group>"; };
    1001510016                77C13F042165658A002D9C5F /* JSIntersectionObserverEntryCustom.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSIntersectionObserverEntryCustom.cpp; sourceTree = "<group>"; };
    1001610017                77CAAAEF1F2FC35000CB5C8D /* VisualViewport.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VisualViewport.idl; sourceTree = "<group>"; };
     
    2236422365                                51E269321DD3BC43006B6A58 /* JSIDBTransactionCustom.cpp */,
    2236522366                                A7D0318D0E93540300E24ACD /* JSImageDataCustom.cpp */,
     22367                                5868C7D52546E0B300BF9DF3 /* JSIntersectionObserverCustom.cpp */,
    2236622368                                77C13F042165658A002D9C5F /* JSIntersectionObserverEntryCustom.cpp */,
    2236722369                                CD0320152279F5BF00DD9F0B /* JSMediaCapabilitiesCustom.h */,
  • trunk/Source/WebCore/bindings/js/JSIntersectionObserverCustom.cpp

    r269137 r269141  
    11/*
    2  * Copyright (C) 2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2020 Igalia S.L.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 // https://wicg.github.io/IntersectionObserver/
     26#include "config.h"
     27#include "JSIntersectionObserver.h"
    2728
    28 [
    29     Conditional=INTERSECTION_OBSERVER,
    30     CallbackThisObject=IntersectionObserver,
    31 ] callback IntersectionObserverCallback = undefined (sequence<IntersectionObserverEntry> entries, IntersectionObserver observer);
     29#include <JavaScriptCore/JSCInlines.h>
     30
     31namespace WebCore {
     32
     33void JSIntersectionObserver::visitAdditionalChildren(JSC::SlotVisitor& visitor)
     34{
     35    if (auto* callback = wrapped().callbackConcurrently())
     36        callback->visitJSFunction(visitor);
     37}
     38
     39}
  • trunk/Source/WebCore/page/IntersectionObserver.h

    r260736 r269141  
    100100    void notify();
    101101
     102    IntersectionObserverCallback* callbackConcurrently() { return m_callback.get(); }
     103
    102104private:
    103105    IntersectionObserver(Document&, Ref<IntersectionObserverCallback>&&, ContainerNode* root, LengthBox&& parsedRootMargin, Vector<double>&& thresholds);
  • trunk/Source/WebCore/page/IntersectionObserver.idl

    r267813 r269141  
    3030    Conditional=INTERSECTION_OBSERVER,
    3131    EnabledBySetting=IntersectionObserver,
    32     Exposed=Window
     32    Exposed=Window,
     33    JSCustomMarkFunction,
    3334] interface IntersectionObserver {
    3435    [CallWith=Document] constructor(IntersectionObserverCallback callback, optional IntersectionObserverInit options);
  • trunk/Source/WebCore/page/IntersectionObserverCallback.h

    r265397 r269141  
    4242    using ActiveDOMCallback::ActiveDOMCallback;
    4343
     44    virtual bool hasCallback() const { return false; }
     45
    4446    virtual CallbackResult<void> handleEvent(IntersectionObserver&, const Vector<Ref<IntersectionObserverEntry>>&, IntersectionObserver&) = 0;
    4547};
  • trunk/Source/WebCore/page/IntersectionObserverCallback.idl

    r266311 r269141  
    2929    Conditional=INTERSECTION_OBSERVER,
    3030    CallbackThisObject=IntersectionObserver,
     31    IsWeakCallback,
    3132] callback IntersectionObserverCallback = undefined (sequence<IntersectionObserverEntry> entries, IntersectionObserver observer);
Note: See TracChangeset for help on using the changeset viewer.