WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
190235
IntersectionObserver doesn't keep target's JS wrapper alive
https://bugs.webkit.org/show_bug.cgi?id=190235
Summary
IntersectionObserver doesn't keep target's JS wrapper alive
Ryosuke Niwa
Reported
2018-10-02 22:55:04 PDT
When an element is enqueued as an IntersectionObserverEntry and subsequently removed from the document, there is no way for JSC GC to know the JS wrapper of the element needs to be kept alive. As such, the JS wrapper of an element can be erroneously collected.
Attachments
Patch
(15.41 KB, patch)
2018-10-04 10:53 PDT
,
Ali Juma
no flags
Details
Formatted Diff
Diff
Patch
(15.44 KB, patch)
2018-10-04 12:20 PDT
,
Ali Juma
no flags
Details
Formatted Diff
Diff
Patch
(19.58 KB, patch)
2018-10-22 14:38 PDT
,
Ali Juma
no flags
Details
Formatted Diff
Diff
Patch
(20.16 KB, patch)
2018-11-05 11:08 PST
,
Ali Juma
no flags
Details
Formatted Diff
Diff
Patch for landing
(29.26 KB, patch)
2018-11-06 11:52 PST
,
Ali Juma
no flags
Details
Formatted Diff
Diff
Show Obsolete
(4)
View All
Add attachment
proposed patch, testcase, etc.
Ryosuke Niwa
Comment 1
2018-10-02 23:02:32 PDT
We need to deploy GCReachableRef for every target kept alive in IntersectionObserver as I've done in
https://trac.webkit.org/changeset/236781
, and need to add the root(m_target) as an opaque root in JSIntersectionObserverEntry::visitAdditionalChildren. (Add JSCustomMarkFunction to the IDL file). IntersectionObserver itself has a bug that it doesn't keep its callback alive while there are pending records. We need to override its visitAdditionalChildren and isReachableFromOpaqueRoots as done in JSMutationObserverCustom.
Radar WebKit Bug Importer
Comment 2
2018-10-02 23:03:30 PDT
<
rdar://problem/44965676
>
Ryosuke Niwa
Comment 3
2018-10-02 23:04:39 PDT
Note that this bug will have a dire consequence of turning a custom element into a HTMLUnknownElement so we MUST fix this bug before we can turn the feature on by default.
Ali Juma
Comment 4
2018-10-04 10:53:04 PDT
Created
attachment 351601
[details]
Patch
Ali Juma
Comment 5
2018-10-04 10:56:57 PDT
(In reply to Ryosuke Niwa from
comment #1
) >
> IntersectionObserver itself has a bug that it doesn't keep its callback > alive while there are pending records. We need to override its > visitAdditionalChildren and isReachableFromOpaqueRoots as done in > JSMutationObserverCustom.
MutationObserver uses a WeakCallback (see MutationCallback.idl), but IntersectionObserver does not. So the callback won't get GC'd, as long as we don't clear IntersectionObserver::m_callback. There was, however, a bug in IntersectionObserver::hasPendingActivity, since this didn't account for pending records (so the IntersectionObserver itself could have gotten GC'd while it still had pending records). That bug is fixed in the patch.
Geoffrey Garen
Comment 6
2018-10-04 12:00:40 PDT
Comment on
attachment 351601
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=351601&action=review
> Source/WebCore/bindings/js/JSIntersectionObserverEntryCustom.cpp:33 > + visitor.addOpaqueRoot(wrapped().target());
This looks wrong. The opaque root needs to be the root of the data structure. "root(wrapped().target())" will probably do what you need.
Ali Juma
Comment 7
2018-10-04 12:20:06 PDT
Created
attachment 351612
[details]
Patch
Ali Juma
Comment 8
2018-10-04 12:20:48 PDT
Comment on
attachment 351601
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=351601&action=review
>> Source/WebCore/bindings/js/JSIntersectionObserverEntryCustom.cpp:33 >> + visitor.addOpaqueRoot(wrapped().target()); > > This looks wrong. The opaque root needs to be the root of the data structure. "root(wrapped().target())" will probably do what you need.
Ah, thanks! Fixed now.
Ryosuke Niwa
Comment 9
2018-10-04 22:36:33 PDT
Comment on
attachment 351612
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=351612&action=review
> Source/WebCore/ChangeLog:19 > + No new tests, since the races fixed here are difficult to test reliably. See
r236801
and
r236825
for similar > + fixes to MutationObserver that also had to land without tests.
See my tests in
https://trac.webkit.org/changeset/236850/webkit
. We should be able to add similar tests.
Ali Juma
Comment 10
2018-10-22 14:38:45 PDT
Created
attachment 352910
[details]
Patch Added tests
Ali Juma
Comment 11
2018-11-05 11:08:07 PST
Created
attachment 353889
[details]
Patch
Simon Fraser (smfr)
Comment 12
2018-11-05 11:32:33 PST
Chris, could you review?
Ryosuke Niwa
Comment 13
2018-11-05 20:42:13 PST
Comment on
attachment 353889
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=353889&action=review
r=me with one additional test.
> Source/WebCore/page/IntersectionObserverEntry.h:62 > RefPtr<DOMRectReadOnly> rootBounds() const { return m_rootBounds; } > RefPtr<DOMRectReadOnly> boundingClientRect() const { return m_boundingClientRect; } > RefPtr<DOMRectReadOnly> intersectionRect() const { return m_intersectionRect; }
DOMRectReadOnly have the same issue. We need to visit these objects' wrappers as well. Otherwise, properties added on DOMRectReadOnly would be collected. But that could be addressed in a separate patch.
> LayoutTests/intersection-observer/root-element-deleted.html:23 > requestAnimationFrame(t.step_func_done(function() { > + observer.takeRecords();
We should add another test which doesn't rely on takeRecords to make sure deliver() path results in the clearing of GCReachableRef as well.
Ali Juma
Comment 14
2018-11-06 11:52:29 PST
Created
attachment 353982
[details]
Patch for landing
Ali Juma
Comment 15
2018-11-06 11:54:03 PST
(In reply to Ryosuke Niwa from
comment #13
)
> Comment on
attachment 353889
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=353889&action=review
> > r=me with one additional test. > > > Source/WebCore/page/IntersectionObserverEntry.h:62 > > RefPtr<DOMRectReadOnly> rootBounds() const { return m_rootBounds; } > > RefPtr<DOMRectReadOnly> boundingClientRect() const { return m_boundingClientRect; } > > RefPtr<DOMRectReadOnly> intersectionRect() const { return m_intersectionRect; } > > DOMRectReadOnly have the same issue. > We need to visit these objects' wrappers as well. > Otherwise, properties added on DOMRectReadOnly would be collected. > But that could be addressed in a separate patch.
Thanks for pointing this out, I'll fix this in a follow-up patch.
> > LayoutTests/intersection-observer/root-element-deleted.html:23 > > requestAnimationFrame(t.step_func_done(function() { > > + observer.takeRecords(); > > We should add another test which doesn't rely on takeRecords to make sure > deliver() path results in the clearing of GCReachableRef as well.
Added a test.
Ryosuke Niwa
Comment 16
2018-11-06 11:59:24 PST
(In reply to Ali Juma from
comment #15
)
> (In reply to Ryosuke Niwa from
comment #13
) > > Comment on
attachment 353889
[details]
> > Patch > > > > View in context: > >
https://bugs.webkit.org/attachment.cgi?id=353889&action=review
> > > > r=me with one additional test. > > > > > Source/WebCore/page/IntersectionObserverEntry.h:62 > > > RefPtr<DOMRectReadOnly> rootBounds() const { return m_rootBounds; } > > > RefPtr<DOMRectReadOnly> boundingClientRect() const { return m_boundingClientRect; } > > > RefPtr<DOMRectReadOnly> intersectionRect() const { return m_intersectionRect; } > > > > DOMRectReadOnly have the same issue. > > We need to visit these objects' wrappers as well. > > Otherwise, properties added on DOMRectReadOnly would be collected. > > But that could be addressed in a separate patch. > > Thanks for pointing this out, I'll fix this in a follow-up patch.
Be sure to make these methods return a pointer instead when you do that since visitAdditionalChildren can be called from non-main threads.
WebKit Commit Bot
Comment 17
2018-11-06 12:52:59 PST
Comment on
attachment 353982
[details]
Patch for landing Clearing flags on attachment: 353982 Committed
r237880
: <
https://trac.webkit.org/changeset/237880
>
WebKit Commit Bot
Comment 18
2018-11-06 12:53:02 PST
All reviewed patches have been landed. Closing bug.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug