WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
233025
Defining a custom element should not cause global object's structure transitions
https://bugs.webkit.org/show_bug.cgi?id=233025
Summary
Defining a custom element should not cause global object's structure transitions
Alexey Shvayka
Reported
2021-11-11 16:57:02 PST
JSCustomElementInterface should keep strong references to constructor / callbacks
Attachments
Patch
(9.15 KB, patch)
2021-11-11 17:00 PST
,
Alexey Shvayka
ggaren
: review-
ews-feeder
: commit-queue-
Details
Formatted Diff
Diff
View All
Add attachment
proposed patch, testcase, etc.
Alexey Shvayka
Comment 1
2021-11-11 17:00:34 PST
Created
attachment 444026
[details]
Patch
Geoffrey Garen
Comment 2
2021-11-12 10:05:12 PST
Comment on
attachment 444026
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=444026&action=review
> Source/WebCore/bindings/js/JSCustomElementInterface.h:104 > + JSC::Strong<JSC::JSObject> m_constructor; > + JSC::Strong<JSC::JSObject> m_connectedCallback; > + JSC::Strong<JSC::JSObject> m_disconnectedCallback; > + JSC::Strong<JSC::JSObject> m_adoptedCallback; > + JSC::Strong<JSC::JSObject> m_attributeChangedCallback;
Unfortunately, it can't be this simple because this would create a retain cycle that can't be broken by GC. I think you could achieve something similarly elegant if you used JSValueInWrappedObject, and had the global object or the document visit this registry and these values during GC, in visitAdditionalChildren.
Darin Adler
Comment 3
2021-11-12 11:35:22 PST
Comment on
attachment 444026
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=444026&action=review
>> Source/WebCore/bindings/js/JSCustomElementInterface.h:104 >> + JSC::Strong<JSC::JSObject> m_attributeChangedCallback; > > Unfortunately, it can't be this simple because this would create a retain cycle that can't be broken by GC. > > I think you could achieve something similarly elegant if you used JSValueInWrappedObject, and had the global object or the document visit this registry and these values during GC, in visitAdditionalChildren.
Also, we should create the test case that shows this. I made a lot of those when I first created JSValueInWrappedObject and started to deploy it to fix the retain cycles we had back then that can’t be broken by GC.
Alexey Shvayka
Comment 4
2021-11-15 10:03:41 PST
Dear Geoff and Darin, Could you please help me understand adverse effects of having a strong reference in this particular case? I agree that in general case this is bad, but JSCustomElementInterface can't possibly be destructed until a global object -- which holds a strong reference to never-destructible CustomElementRegistry, which in turn holds strong references to its JSCustomElementInterface -- is dead. Custom element interfaces can't be removed from the registry per spec, only added. Even a cross-realm callback / constructor, which is only reference to its global object, can't be released per spec as custom element interface definition should hold a strong reference to it.
Darin Adler
Comment 5
2021-11-15 10:24:05 PST
If you can’t make a test showing a leak, then I think the leak probably doesn’t exist. I was taking Geoff’s word for it, and drawing analogy with other similar places, not assessing whether a strong reference was a problem.
Geoffrey Garen
Comment 6
2021-11-17 11:01:27 PST
> Custom element interfaces can't be removed from the registry per spec, only > added. Even a cross-realm callback / constructor, which is only reference to > its global object, can't be released per spec as custom element interface > definition should hold a strong reference to it.
I think this means that there's no noticeable memory leak for the duration of an individual window/document on screen, but once the window/document is off screen and otherwise unreachable, that's the case where the JSC::Strong will cause a noticeable memory leak. The easiest ways to trigger this condition in a test are: insert and <iframe> into a document and then remove it (repeatedly); or navigate an <iframe> (repeatedly).
Radar WebKit Bug Importer
Comment 7
2021-11-18 16:57:23 PST
<
rdar://problem/85574850
>
Alexey Shvayka
Comment 8
2022-08-05 17:12:30 PDT
Pull request:
https://github.com/WebKit/WebKit/pull/3066
Alexey Shvayka
Comment 9
2022-08-05 17:13:09 PDT
(In reply to Geoffrey Garen from
comment #6
)
> > Custom element interfaces can't be removed from the registry per spec, only > > added. Even a cross-realm callback / constructor, which is only reference to > > its global object, can't be released per spec as custom element interface > > definition should hold a strong reference to it. > > I think this means that there's no noticeable memory leak for the duration > of an individual window/document on screen, but once the window/document is > off screen and otherwise unreachable, that's the case where the JSC::Strong > will cause a noticeable memory leak. The easiest ways to trigger this > condition in a test are: insert and <iframe> into a document and then remove > it (repeatedly); or navigate an <iframe> (repeatedly).
Thank you for your help on this, Geoff. I've managed to prove that Strong causes a memory leak with cross-realm callback and WeakRef. Updated the patch to rely on visitAdditionalChildren() just as you suggested.
EWS
Comment 10
2022-08-11 07:23:29 PDT
Committed
253330@main
(1b11bc2ebce8): <
https://commits.webkit.org/253330@main
> Reviewed commits have been landed. Closing PR #3066 and removing active labels.
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