Bug 148472 - Remove all uses of PassRefPtr in WebCore/svg
Summary: Remove all uses of PassRefPtr in WebCore/svg
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Gyuyoung Kim
URL:
Keywords:
Depends on:
Blocks: 144092
  Show dependency treegraph
 
Reported: 2015-08-26 02:06 PDT by Gyuyoung Kim
Modified: 2015-09-09 19:16 PDT (History)
3 users (show)

See Also:


Attachments
Patch (18.23 KB, patch)
2015-08-26 02:07 PDT, Gyuyoung Kim
no flags Details | Formatted Diff | Diff
Patch (26.12 KB, patch)
2015-08-26 05:06 PDT, Gyuyoung Kim
no flags Details | Formatted Diff | Diff
Patch (26.10 KB, patch)
2015-08-26 22:38 PDT, Gyuyoung Kim
no flags Details | Formatted Diff | Diff
Patch (27.41 KB, patch)
2015-09-01 18:42 PDT, Gyuyoung Kim
no flags Details | Formatted Diff | Diff
Patch (28.06 KB, patch)
2015-09-02 19:44 PDT, Gyuyoung Kim
no flags Details | Formatted Diff | Diff
Patch (28.06 KB, patch)
2015-09-02 20:22 PDT, Gyuyoung Kim
no flags Details | Formatted Diff | Diff
Patch (28.10 KB, patch)
2015-09-08 23:40 PDT, Gyuyoung Kim
no flags Details | Formatted Diff | Diff
Patch (29.06 KB, patch)
2015-09-09 01:31 PDT, Gyuyoung Kim
no flags Details | Formatted Diff | Diff
Patch (29.06 KB, patch)
2015-09-09 02:00 PDT, Gyuyoung Kim
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Gyuyoung Kim 2015-08-26 02:06:32 PDT
SSIA
Comment 1 Gyuyoung Kim 2015-08-26 02:07:14 PDT
Created attachment 259940 [details]
Patch
Comment 2 Gyuyoung Kim 2015-08-26 05:06:18 PDT
Created attachment 259944 [details]
Patch
Comment 3 Daniel Bates 2015-08-26 20:17:28 PDT
Comment on attachment 259944 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=259944&action=review

> Source/WebCore/dom/Node.cpp:1874
> +    if (!targetNode->EventTarget::addEventListener(eventType, WTF::move(listener), useCapture))

This is not correct because we reference listener later in this function (line 1892) and listener will be nullified on return of the implicitly invoked RefPtr move constructor. We should use listener.copyRef() here.

> Source/WebCore/html/ImageDocument.cpp:242
> +            window->addEventListener("resize", WTF::move(listener), false);

Similarly, we should use listener.copyRef() here.

> Source/WebCore/html/shadow/MediaControlsApple.cpp:512
> +    m_closedCaptionsContainer->addEventListener(eventNames().wheelEvent, WTF::move(listener), true);

Ditto.

> Source/WebCore/html/shadow/MediaControlsApple.cpp:519
> +    document().addEventListener(eventNames().clickEvent, WTF::move(listener), true);

Ditto.

> Source/WebCore/html/shadow/MediaControlsApple.cpp:520
> +    addEventListener(eventNames().clickEvent, WTF::move(listener), true);

Ditto.

> Source/WebCore/page/DOMWindow.cpp:1697
> +    if (!EventTarget::addEventListener(eventType, WTF::move(listener), useCapture))

We may want to consider using listener.copyRef() here to make using listener after this line less error prone given the length of this function.

> Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp:90
> +        builder->appendEffectToEffectReferences(WTF::move(effect), element.renderer());

This is not correct since we dereference effect below. We should use effect.copyRef() here.

> Source/WebCore/svg/SVGElement.cpp:579
> +    if (!Node::addEventListener(eventType, WTF::move(listener), useCapture))

Similarly, we should use listener.copyRef() here.

> Source/WebCore/svg/SVGElement.cpp:589
> +        bool result = instance->Node::addEventListener(eventType, WTF::move(listener), useCapture);

Although not strictly necessary, I suggest we use listener.copyRef() here as well.

> Source/WebCore/svg/SVGPathElement.cpp:362
> +            appendSVGPathByteStreamFromSVGPathSeg(WTF::move(m_pathSegList.value.last()), m_pathByteStream.get(), UnalteredParsing);

We should use copyRef() here.

> Source/WebCore/svg/SVGTRefElement.cpp:252
> +        m_targetListener->attach(WTF::move(target));

This is not correct and will cause target.get() to return nullptr on line 254 because target will be nullified on return of the implicitly invoked RefPtr move constructor. We should use target.copyRef().
Comment 4 Gyuyoung Kim 2015-08-26 22:38:06 PDT
Comment on attachment 259944 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=259944&action=review

>> Source/WebCore/dom/Node.cpp:1874
>> +    if (!targetNode->EventTarget::addEventListener(eventType, WTF::move(listener), useCapture))
> 
> This is not correct because we reference listener later in this function (line 1892) and listener will be nullified on return of the implicitly invoked RefPtr move constructor. We should use listener.copyRef() here.

Nice point out ! Fixed. Let me take care of this in upcoming patch.

>> Source/WebCore/html/ImageDocument.cpp:242
>> +            window->addEventListener("resize", WTF::move(listener), false);
> 
> Similarly, we should use listener.copyRef() here.

done.

>> Source/WebCore/html/shadow/MediaControlsApple.cpp:512
>> +    m_closedCaptionsContainer->addEventListener(eventNames().wheelEvent, WTF::move(listener), true);
> 
> Ditto.

done.

>> Source/WebCore/html/shadow/MediaControlsApple.cpp:520
>> +    addEventListener(eventNames().clickEvent, WTF::move(listener), true);
> 
> Ditto.

This line is last use of *listener*. Should we use copyRef() here as well ?

>> Source/WebCore/svg/SVGElement.cpp:589
>> +        bool result = instance->Node::addEventListener(eventType, WTF::move(listener), useCapture);
> 
> Although not strictly necessary, I suggest we use listener.copyRef() here as well.

*listener* is used in this function lastly. Isn't it WTF::move() better ?

>> Source/WebCore/svg/SVGPathElement.cpp:362
>> +            appendSVGPathByteStreamFromSVGPathSeg(WTF::move(m_pathSegList.value.last()), m_pathByteStream.get(), UnalteredParsing);
> 
> We should use copyRef() here.

done.

>> Source/WebCore/svg/SVGTRefElement.cpp:252
>> +        m_targetListener->attach(WTF::move(target));
> 
> This is not correct and will cause target.get() to return nullptr on line 254 because target will be nullified on return of the implicitly invoked RefPtr move constructor. We should use target.copyRef().

done.
Comment 5 Gyuyoung Kim 2015-08-26 22:38:39 PDT
Created attachment 260034 [details]
Patch
Comment 6 Gyuyoung Kim 2015-08-30 20:14:07 PDT
dydz, could you take a look again ?
Comment 7 Darin Adler 2015-09-01 10:49:14 PDT
Comment on attachment 260034 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=260034&action=review

> Source/WebCore/dom/EventListenerMap.cpp:190
> +        target->addEventListener(eventType, WTF::move((*listenerVector)[i].listener), (*listenerVector)[i].useCapture);

I’m concerned about this. Is this already how the code behaved, or is this new behavior? I don’t think a behavior change should be mixed in with the rest of the patch. At first this should be copyRef and then we could use WTF::move to optimize and think through whether that’s OK.

> Source/WebCore/dom/EventTarget.cpp:79
>      return ensureEventTargetData().eventListenerMap.add(eventType, listener, useCapture);

Do we need WTF::move here to avoid reference count churn?

> Source/WebCore/dom/Node.cpp:1910
>      return tryAddEventListener(this, eventType, listener, useCapture);

Do we need WTF::move here to avoid reference count churn?

> Source/WebCore/html/HTMLMediaElement.cpp:5045
> +bool HTMLMediaElement::addEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)

Do we need to add some WTF::move to this function to avoid reference count churn?

> Source/WebCore/svg/SVGPathUtilities.cpp:142
> +bool appendSVGPathByteStreamFromSVGPathSeg(RefPtr<SVGPathSeg>&& pathSeg, SVGPathByteStream* result, PathParsingMode parsingMode)

I think we need WTF::move below on the call to append to avoid adding reference count churn.

> Source/WebCore/svg/SVGTRefElement.cpp:89
> +void SVGTRefTargetEventListener::attach(RefPtr<Element>&& target)

Don’t we need WTF::move on the assignment to m_target below?

> Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp:67
>      RefPtr<FilterEffect> effect = prpEffect;

We need WTF::move here. Also seems this function is not taking advantage of the fact that we can take ownership of the effect passed in.

It’s not good to leave things named with a “prp” prefix when they are not using PassRefPtr.
Comment 8 Gyuyoung Kim 2015-09-01 18:42:58 PDT
Created attachment 260399 [details]
Patch
Comment 9 Gyuyoung Kim 2015-09-01 18:44:09 PDT
(In reply to comment #7)
> Comment on attachment 260034 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=260034&action=review
> 
> > Source/WebCore/dom/EventListenerMap.cpp:190
> > +        target->addEventListener(eventType, WTF::move((*listenerVector)[i].listener), (*listenerVector)[i].useCapture);
> 
> I’m concerned about this. Is this already how the code behaved, or is this
> new behavior? I don’t think a behavior change should be mixed in with the
> rest of the patch. At first this should be copyRef and then we could use
> WTF::move to optimize and think through whether that’s OK.
> 
> > Source/WebCore/dom/EventTarget.cpp:79
> >      return ensureEventTargetData().eventListenerMap.add(eventType, listener, useCapture);
> 
> Do we need WTF::move here to avoid reference count churn?
> 
> > Source/WebCore/dom/Node.cpp:1910
> >      return tryAddEventListener(this, eventType, listener, useCapture);
> 
> Do we need WTF::move here to avoid reference count churn?
> 
> > Source/WebCore/html/HTMLMediaElement.cpp:5045
> > +bool HTMLMediaElement::addEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
> 
> Do we need to add some WTF::move to this function to avoid reference count
> churn?
> 
> > Source/WebCore/svg/SVGPathUtilities.cpp:142
> > +bool appendSVGPathByteStreamFromSVGPathSeg(RefPtr<SVGPathSeg>&& pathSeg, SVGPathByteStream* result, PathParsingMode parsingMode)
> 
> I think we need WTF::move below on the call to append to avoid adding
> reference count churn.
> 
> > Source/WebCore/svg/SVGTRefElement.cpp:89
> > +void SVGTRefTargetEventListener::attach(RefPtr<Element>&& target)
> 
> Don’t we need WTF::move on the assignment to m_target below?
> 
> > Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp:67
> >      RefPtr<FilterEffect> effect = prpEffect;
> 
> We need WTF::move here. Also seems this function is not taking advantage of
> the fact that we can take ownership of the effect passed in.
> 
> It’s not good to leave things named with a “prp” prefix when they are not
> using PassRefPtr.

Because this is first patch to reduce uses of PassRefPtr in argument, I had unclear understanding in some cases. If there is still wrong changes, please let me know.
Comment 10 Darin Adler 2015-09-02 09:28:58 PDT
(In reply to comment #9)
> Because this is first patch to reduce uses of PassRefPtr in argument, I had
> unclear understanding in some cases. If there is still wrong changes, please
> let me know.

I won’t be able to answer all the questions from just reading the code. We may have to actually test things to make sure we are choosing the correct idioms before we make changes across the entire project!
Comment 11 Darin Adler 2015-09-02 09:34:53 PDT
Comment on attachment 260399 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=260399&action=review

Some initial comments.

> Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp:216
> +    bool success = AudioNode::addEventListener(eventType, listener.copyRef(), useCapture);

This is not quite right. The old code passed the listener in without churning the reference count; that’s what passing a PassRefPtr to another function that also takes a PassRefPtr does. But the new code is doing a copyRef; the whole point of taking RefPtr&& is to be able to move the thing in and take ownership without churning the reference count. There are two ways to do this:

1) Use Ref&& or RefPtr&& so we can avoid churning the reference count.
2) Use & or * so the caller doesn’t have to already hold the thing in a smart pointer.

But we should never take a Ref&& or RefPtr&& and then decide to unconditionally do a copyRef. That’s wasteful and even slightly misleading.

I’m pretty sure we need to use WTF::move, not copyRef, here. Or maybe we can pass without an explicit WTF::move. I’m not sure about that. What I do know is that we want the compiled code for this function to not change there reference count of listener at all.

> Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp:278
> +    bool success = AudioNode::addEventListener(eventType, listener.copyRef(), useCapture);

Same thing.

> Source/WebCore/html/HTMLMediaElement.cpp:5051
>          return Node::addEventListener(eventType, listener, useCapture);

Will this do the right thing without a call to WTF::move or not? We need to know before we land this change.
Comment 12 Gyuyoung Kim 2015-09-02 19:29:24 PDT
Comment on attachment 260399 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=260399&action=review

>> Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp:216
>> +    bool success = AudioNode::addEventListener(eventType, listener.copyRef(), useCapture);
> 
> This is not quite right. The old code passed the listener in without churning the reference count; that’s what passing a PassRefPtr to another function that also takes a PassRefPtr does. But the new code is doing a copyRef; the whole point of taking RefPtr&& is to be able to move the thing in and take ownership without churning the reference count. There are two ways to do this:
> 
> 1) Use Ref&& or RefPtr&& so we can avoid churning the reference count.
> 2) Use & or * so the caller doesn’t have to already hold the thing in a smart pointer.
> 
> But we should never take a Ref&& or RefPtr&& and then decide to unconditionally do a copyRef. That’s wasteful and even slightly misleading.
> 
> I’m pretty sure we need to use WTF::move, not copyRef, here. Or maybe we can pass without an explicit WTF::move. I’m not sure about that. What I do know is that we want the compiled code for this function to not change there reference count of listener at all.

Now I pretty feel that we should very take care of purging PassRefPtr in argument. To my understanding we should use copyRef() when the argument is used in multiple lines. If the argument is just passed to a new function or code calling RefPtr::release(), we need to pass the ownership to new function using WTF::move(),

for example,

void foo(RefPtr<EventListener>&& listener)
{
    aVar(listener.copyRef());
    ...
    bVar(listener.copyRef()); => I wonder what should we use in last use of function. copyRef() or WTF::move() ?
}


However we have to move ownership of the argument when function just passes the argument to new function even when RefPtr::release() is not used as below, right ?

void foo(RefPtr<EventListener>&& listener)
{
    aVar(WTF::move(listener));
}
Comment 13 Darin Adler 2015-09-02 19:33:18 PDT
(In reply to comment #12)
>     bVar(listener.copyRef()); => I wonder what should we use in last use of
> function. copyRef() or WTF::move() ?

Should use WTF::move, I think.

> However we have to move ownership of the argument when function just passes
> the argument to new function even when RefPtr::release() is not used as
> below, right ?
> 
> void foo(RefPtr<EventListener>&& listener)
> {
>     aVar(WTF::move(listener));
> }

I believe so, but I am not sure; might work without explicit WTF::move. Best way to find out would be to write some unit tests.
Comment 14 Gyuyoung Kim 2015-09-02 19:44:43 PDT
Created attachment 260475 [details]
Patch
Comment 15 Gyuyoung Kim 2015-09-02 19:49:37 PDT
Comment on attachment 260475 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=260475&action=review

> Source/WebCore/html/HTMLMediaElement.cpp:5054
> +    if (!Node::addEventListener(eventType, listener.copyRef(), useCapture))

I wonder what should we use here. Because here is last use of *listener*.

> Source/WebCore/html/ImageDocument.cpp:243
> +        imageElement->addEventListener("click", WTF::move(listener), false);

I believe we have to use WTF::move() since listener is released in original code.

> Source/WebCore/html/shadow/MediaControlsApple.cpp:520
> +    addEventListener(eventNames().clickEvent, listener.copyRef(), true);

ditto. Last use.

> Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp:94
> +        builder->add(element.result(), WTF::move(effect));

.release() should be replaced with WTF::move() in order to pass an ownership.

> Source/WebCore/svg/SVGPathUtilities.cpp:149
> +    appendedItemList.append(pathSeg.copyRef());

Should we pass ownership of *pathSeg* when appending RefPtr&& ?

> Source/WebCore/svg/SVGTRefElement.cpp:97
> +    m_target = WTF::move(target);

I'm not sure if we have to use WTF::move(). Isn't copyRef() correct ?
Comment 16 Gyuyoung Kim 2015-09-02 20:22:49 PDT
Created attachment 260480 [details]
Patch
Comment 17 Gyuyoung Kim 2015-09-02 20:23:19 PDT
(In reply to comment #13)
> (In reply to comment #12)
> >     bVar(listener.copyRef()); => I wonder what should we use in last use of
> > function. copyRef() or WTF::move() ?
> 
> Should use WTF::move, I think.
> 
> > However we have to move ownership of the argument when function just passes
> > the argument to new function even when RefPtr::release() is not used as
> > below, right ?
> > 
> > void foo(RefPtr<EventListener>&& listener)
> > {
> >     aVar(WTF::move(listener));
> > }
> 
> I believe so, but I am not sure; might work without explicit WTF::move. Best
> way to find out would be to write some unit tests.

Ok, let me prepare some unit tests for this issue soon.
Comment 18 Darin Adler 2015-09-08 18:58:04 PDT
Comment on attachment 260480 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=260480&action=review

Looks like we missed something in Node.cpp according to iOS. Looks generally good but please consider my comments.

> Source/WebCore/dom/EventListenerMap.cpp:190
> +        target->addEventListener(eventType, ((*listenerVector)[i].listener).copyRef(), (*listenerVector)[i].useCapture);

I don’t think we need those extra parentheses.

> Source/WebCore/html/HTMLMediaElement.cpp:5051
> +        return Node::addEventListener(eventType, listener.copyRef(), useCapture);

This should be WTF::move, not copyRef.

> Source/WebCore/page/DOMWindow.cpp:1697
> +    if (!EventTarget::addEventListener(eventType, listener.copyRef(), useCapture))

This should be WTF::move, not copyRef. None of the code below uses listener.

> Source/WebCore/svg/SVGElement.cpp:574
> +bool SVGElement::addEventListener(const AtomicString& eventType, RefPtr<EventListener>&& prpListener, bool useCapture)

This could just be named listener. No need for the prpListener name.

> Source/WebCore/svg/SVGElement.cpp:576
>      RefPtr<EventListener> listener = prpListener;

Don’t need this local.

> Source/WebCore/svg/SVGPathUtilities.cpp:149
> +    appendedItemList.append(pathSeg.copyRef());

Seems to me that this should be WTF::move, not copyRef.

> Source/WebCore/svg/SVGTRefElement.cpp:68
> +    void attach(RefPtr<Element>&& target);

I think it’s a bit peculiar that this is RefPtr<Element>&& instead of just Element&.

> Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp:65
> +void SVGFilterBuilder::appendEffectToEffectReferences(RefPtr<FilterEffect>&& filterEffect, RenderObject* object)

This should just be named "effect".

> Source/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp:67
> +    RefPtr<FilterEffect> effect = WTF::move(filterEffect);

No need for this.
Comment 19 Gyuyoung Kim 2015-09-08 23:40:01 PDT
Comment on attachment 260480 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=260480&action=review

>> Source/WebCore/html/HTMLMediaElement.cpp:5051
>> +        return Node::addEventListener(eventType, listener.copyRef(), useCapture);
> 
> This should be WTF::move, not copyRef.

Right. Nice catch !

>> Source/WebCore/page/DOMWindow.cpp:1697
>> +    if (!EventTarget::addEventListener(eventType, listener.copyRef(), useCapture))
> 
> This should be WTF::move, not copyRef. None of the code below uses listener.

Thanks.

>> Source/WebCore/svg/SVGTRefElement.cpp:68
>> +    void attach(RefPtr<Element>&& target);
> 
> I think it’s a bit peculiar that this is RefPtr<Element>&& instead of just Element&.

To change to use Element&, it looks there are some additional changes. I would like to modify this in new bug.
Comment 20 Gyuyoung Kim 2015-09-08 23:40:49 PDT
Created attachment 260844 [details]
Patch
Comment 21 Gyuyoung Kim 2015-09-09 01:31:10 PDT
Created attachment 260848 [details]
Patch
Comment 22 Gyuyoung Kim 2015-09-09 02:00:53 PDT
Created attachment 260850 [details]
Patch
Comment 23 WebKit Commit Bot 2015-09-09 19:16:33 PDT
Comment on attachment 260850 [details]
Patch

Clearing flags on attachment: 260850

Committed r189565: <http://trac.webkit.org/changeset/189565>
Comment 24 WebKit Commit Bot 2015-09-09 19:16:38 PDT
All reviewed patches have been landed.  Closing bug.