WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
102555
Store MutationObserver callback in a hidden property for V8
https://bugs.webkit.org/show_bug.cgi?id=102555
Summary
Store MutationObserver callback in a hidden property for V8
Elliott Sprehn
Reported
2012-11-16 13:36:06 PST
Store MutationObserver callback in a hidden property for V8
Attachments
Patch
(5.26 KB, patch)
2012-11-16 13:39 PST
,
Elliott Sprehn
no flags
Details
Formatted Diff
Diff
Patch
(10.82 KB, patch)
2012-11-16 19:24 PST
,
Elliott Sprehn
no flags
Details
Formatted Diff
Diff
Patch
(7.34 KB, patch)
2012-11-16 19:45 PST
,
Elliott Sprehn
no flags
Details
Formatted Diff
Diff
Patch for landing (on behalf of esprehn)
(9.64 KB, patch)
2012-11-20 11:37 PST
,
Adam Klein
no flags
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Elliott Sprehn
Comment 1
2012-11-16 13:39:13 PST
Created
attachment 174752
[details]
Patch
Elliott Sprehn
Comment 2
2012-11-16 13:40:04 PST
This is the smallest possible change, and it allows us to keep all the existing code related to callback handling.
Adam Barth
Comment 3
2012-11-16 14:09:05 PST
Comment on
attachment 174752
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=174752&action=review
This looks great. My only question is whether V8WeakCallback is really a property of the MutationCallback or whether it is functionality that all callbacks should have that V8MutationObserver activates in V8MutationObserver::constructorCallback.
> Source/WebCore/bindings/scripts/CodeGeneratorV8.pm:3325 > + ${className}* wrapper = static_cast<${className}*>(parameter);
I'm not sure wrapper is the right term here. Perhaps |object| ?
> Source/WebCore/bindings/scripts/CodeGeneratorV8.pm:3386 > + m_callback.Dispose();
Should m_callback be a ScopedPersistent? You seem to be re-implementing the ScopedPersistent pattern. We can fix that in a followup patch.
Adam Barth
Comment 4
2012-11-16 14:12:35 PST
***
Bug 102553
has been marked as a duplicate of this bug. ***
Elliott Sprehn
Comment 5
2012-11-16 15:05:10 PST
So this fixes the leak with cycles and the callback, but interestingly it seems v8 is smart enough to not keep objects that are not reachable alive so: var observer = new WebKitMutationObserver(function() {}); doesn't actually leak without this patch because v8 knows the callback can't reach observer. but var observer = new WebKitMutationObserver(function() { observer }); does leak. I think there's something even more fundamentally leaky in MutationObservers, because even without leaks once you observe() a node you leak: <script> function noCycles(fn) { var observer = new WebKitMutationObserver(fn); observer.observe(document.body, {attributes:true}) // LEAK!!! } for (i=0; i < 1000; i++) noCycles(function(){}); gc(); window.location.href = 'about:blank'; </script> In this test observers and nodes never get collected. Try loading the file in DRT several times: DumpRenderTree /test.html /test.html /test.html and you get: Content-Type: text/plain layer at (0,0) size 800x600 RenderView at (0,0) size 800x600 layer at (0,0) size 800x8 RenderBlock {HTML} at (0,0) size 800x8 RenderBody {BODY} at (8,8) size 784x0 #EOF #EOF #EOF LEAK: 32 WebCoreNode and if you instrument the constructor and destructor for MutationObserver you have 3000 live MutationObservers when DRT closes.
Elliott Sprehn
Comment 6
2012-11-16 15:06:51 PST
(In reply to
comment #5
)
> ... > I think there's something even more fundamentally leaky in MutationObservers, because even without leaks once you observe() a node you leak: >
That should say "even without *cycles*"
Adam Klein
Comment 7
2012-11-16 15:59:48 PST
I can reproduce Elliott's other leak, but am at something of a loss to explain it. Somehow it appears the Document is being kept alive, and that in turn is keeping all nodes in its tree, as well as any registered observers, alive. So my question is, what's keeping the Document alive?
Adam Klein
Comment 8
2012-11-16 17:07:43 PST
(In reply to
comment #7
)
> I can reproduce Elliott's other leak, but am at something of a loss to explain it. Somehow it appears the Document is being kept alive, and that in turn is keeping all nodes in its tree, as well as any registered observers, alive. So my question is, what's keeping the Document alive?
For the record, this appears to be due to
http://trac.webkit.org/changeset/134830
, which made MutationObserver an ActiveDOMObject.
Adam Klein
Comment 9
2012-11-16 17:21:04 PST
(In reply to
comment #8
)
> (In reply to
comment #7
) > > I can reproduce Elliott's other leak, but am at something of a loss to explain it. Somehow it appears the Document is being kept alive, and that in turn is keeping all nodes in its tree, as well as any registered observers, alive. So my question is, what's keeping the Document alive? > > For the record, this appears to be due to
http://trac.webkit.org/changeset/134830
, which made MutationObserver an ActiveDOMObject.
And, for the record, something like that ActiveDOMObject patch is required for the patch on this bug to be correct, since we now rely on the wrapper to keep things alive appropriately.
Adam Barth
Comment 10
2012-11-16 18:06:48 PST
Yes. We just need to make sure not to claim we have pending activity after stop() is called on the mutation observer.
Elliott Sprehn
Comment 11
2012-11-16 18:11:44 PST
(In reply to
comment #10
)
> Yes. We just need to make sure not to claim we have pending activity after stop() is called on the mutation observer.
Yeah, the complication is that they want observation of Nodes from different documents to work: var OtherFramesObserverClass = iframe.contentWIndow.MutationObserver; var observer = new OtherFramesObserverClass(function() {}); iframe.parentNode.removeChild(iframe); observer.observe(node, { ... }); so stopping all pending activity when the original window's document goes away is not right.
Elliott Sprehn
Comment 12
2012-11-16 19:24:17 PST
Created
attachment 174795
[details]
Patch
Elliott Sprehn
Comment 13
2012-11-16 19:45:30 PST
Created
attachment 174799
[details]
Patch
Elliott Sprehn
Comment 14
2012-11-16 19:47:16 PST
(In reply to
comment #3
)
> (From update of
attachment 174752
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=174752&action=review
> > This looks great. My only question is whether V8WeakCallback is really a property of the MutationCallback or whether it is functionality that all callbacks should have that V8MutationObserver activates in V8MutationObserver::constructorCallback.
I added a new argument to ::create() that lets you pass an owner and put it into a dependent retained like mode.
> > > Source/WebCore/bindings/scripts/CodeGeneratorV8.pm:3325 > > + ${className}* wrapper = static_cast<${className}*>(parameter); > > I'm not sure wrapper is the right term here. Perhaps |object| ?
Done.
> > > Source/WebCore/bindings/scripts/CodeGeneratorV8.pm:3386 > > + m_callback.Dispose(); > > Should m_callback be a ScopedPersistent? You seem to be re-implementing the ScopedPersistent pattern. We can fix that in a followup patch.
Yeah. I added a patch that used ScopedPersistent but I'm nervous about trying to change both things at the same time so I uploaded another without it.
Build Bot
Comment 15
2012-11-17 05:06:44 PST
Comment on
attachment 174799
[details]
Patch
Attachment 174799
[details]
did not pass mac-ews (mac): Output:
http://queues.webkit.org/results/14859738
New failing tests: fast/mutation/leak-cycle-observer-wrapper.html
Adam Barth
Comment 16
2012-11-17 09:50:36 PST
Comment on
attachment 174799
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=174799&action=review
> Source/WebCore/bindings/scripts/CodeGeneratorV8.pm:3287 > - static PassRefPtr<${className}> create(v8::Local<v8::Value> value, ScriptExecutionContext* context) > + static PassRefPtr<${className}> create(v8::Local<v8::Value> value, ScriptExecutionContext* context, v8::Local<v8::Object> owner = (v8::Object*)0)
Is there some reason to require a Local handle here? Also, the way to make a default parameter is as follows: v8::Handle<v8::Object> owner = v8::Handle<v8::Object>() In principle, we don't know that 0 maps to empty (and we don't use C-style casts in WebKit).
> Source/WebCore/bindings/v8/V8HiddenPropertyName.h:52 > + V(callback)
Please put this in alphabetical order.
Elliott Sprehn
Comment 17
2012-11-17 10:09:12 PST
Comment on
attachment 174799
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=174799&action=review
>> Source/WebCore/bindings/scripts/CodeGeneratorV8.pm:3287 >> + static PassRefPtr<${className}> create(v8::Local<v8::Value> value, ScriptExecutionContext* context, v8::Local<v8::Object> owner = (v8::Object*)0) > > Is there some reason to require a Local handle here? Also, the way to make a default parameter is as follows: > > v8::Handle<v8::Object> owner = v8::Handle<v8::Object>() > > In principle, we don't know that 0 maps to empty (and we don't use C-style casts in WebKit).
I used a Local because that's what value is as well. I can change to just v8::Handle.
Elliott Sprehn
Comment 18
2012-11-17 10:15:03 PST
(In reply to
comment #15
)
> (From update of
attachment 174799
[details]
) >
Attachment 174799
[details]
did not pass mac-ews (mac): > Output:
http://queues.webkit.org/results/14859738
> > New failing tests: > fast/mutation/leak-cycle-observer-wrapper.html
Hmm, this is really weird that the test has different output on mac but passes on cr-linux...
Elliott Sprehn
Comment 19
2012-11-19 12:38:17 PST
adamk rolled out my ActiveDOMObject patch so we can't land this now. I'm blocked until we resolve the wrapper drop off.
Adam Klein
Comment 20
2012-11-19 17:59:38 PST
The patch on
bug 102328
is in the cq and fixes the wrapper dropoff bug. Once it lands, this patch should also be safe to land.
Adam Klein
Comment 21
2012-11-20 11:37:21 PST
Created
attachment 175254
[details]
Patch for landing (on behalf of esprehn)
WebKit Review Bot
Comment 22
2012-11-20 11:59:57 PST
Comment on
attachment 175254
[details]
Patch for landing (on behalf of esprehn) Clearing flags on attachment: 175254 Committed
r135305
: <
http://trac.webkit.org/changeset/135305
>
WebKit Review Bot
Comment 23
2012-11-20 12:00: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