Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-21 Thread Alexey Proskuryakov

20.06.2011, в 21:55, David Levin написал(а):

 PassRefPtr is useful even if the function doesn't take any kind of ownership. 
 It's useful when callers want to get rid of ownership, and then they can do 
 that efficiently.
 
 I don't understand this. How it is more efficient to pass ownership if a 
 function isn't taking ownership? It seems like passing in a raw pointer would 
 be the most efficient in this case.

As a concrete example, consider a callback function. It can take a reference to 
an object as an argument - the caller definitely no longer needs this object 
after calling it, while the function may or may not take ownership (in any 
sense of this word). In an extreme case, it will not look at its argument at 
all.

Similarly, a base class implementation of a virtual member function may not do 
anything with its argument, while derived objects will take ownership. It's 
not easy to tell if any of the overrides do (or will in the future) take 
ownership. Yet it's easy to see if ownership is being passed away at call sites.

- WBR, Alexey Proskuryakov

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-20 Thread Maciej Stachowiak

On Jun 19, 2011, at 12:48 PM, Darin Adler wrote:

 The arguments about abandoning PassRefPtr for arguments entirely are 
 attacking a straw man. We know PassRefPtr offers an important optimization 
 and do not want to drop that!

I posited it not as a straw man but rather as an option I myself put on the 
table. Seems most folks agree it is a bad one. Also, examining the pros and 
cons of using PassRefPtr in all the cases where we do now vs in none of the 
cases where we do now sheds light on the relative advantages and disadvantages 
of using it only in some of the cases where we do now.

Note that I listed using PassRefPtr for arguments less often (but not never) as 
a separate option.

 
 On Jun 18, 2011, at 10:58 PM, Maciej Stachowiak wrote:
 
 (1) Use PassRefPtr for every parameter that takes ownership.
 
 I still think this is the appropriate rule, and always have, but I think 
 “takes ownership” is not defined to my satisfaction.
 
 Pro (of using PassRefPtr for every parameter that takes ownership):
   Bright-line rule; fairly clear how to apply it.
 
 This is where my problem comes in. I am not sure what the bright-line rule is.

It's approximately this function will put the relevant parameter in a RefPtr 
data member or global. The DOM is more complicated, because much of the 
internal refcounting is done manually instead of using RefPtrs.

 Generally, in the DOM, the rule is that all reachable objects need to be kept 
 alive, so reference counting is used to implement reachability, which does 
 not match with my sense of the word ownership.

Reference-counted objects have shared ownership. Every object holding a 
reference to any other owns it. We could stop using the word ownership and 
instead of take ownership say take a persistent reference.

 For a shared ownership model there are multiple possible definitions of 
 whether a function takes ownership to an object passed as an argument. Here 
 are some of my attempts to describe the bright line:
 
a) Hands off ownership to what could possibly be the sole owner in most 
 code paths.
b) Keeps a reference to the object after the function completes in most 
 code paths.
c) Takes a reference to the object at least once in most code paths.
 
d) Hands off ownership to what could possibly be the sole owner in some 
 code paths.
e) Keeps a reference to the object after it completes in some code paths.
f) Takes a reference to the object at least once in some code paths.
 
 Is the bright line rule you have in mind (b) or perhaps (e)? Or something not 
 listed here at all?

Yes, (b) or (e). I haven't thought about whether most code paths or some 
code paths makes more sense, but I'm not sure there are a lot of cases in our 
code where it makes a difference.

I don't think it makes sense to talk about a sole owner of a refcounted object. 
If there is a sole owner at any given time, it is at best temporary. PassRefPtr 
is about clearly and efficiently transferring a reference, it doesn't need it 
to necessarily be the sole then-existing reference.

[…snip…]

 Similarly, some functions call out to operations that could cause the last 
 owner for one of their arguments to dereference the object. They are likely 
 to fit into category (c) or (f). In a sense the caller does have to pass 
 ownership of the object, because the operation can only be successfully done 
 if the function takes ownership to make sure the object does not disappear 
 while the code is working with it.

My understanding is that our current rule doesn't call for taking a PassRefPtr 
argument in this case, but I can see how it would make sense and would add 
helpful type checking.

 
 
 I tried to find the examples that bother me. Here are some DOM examples where 
 the term ownership seems wrong, and it’s more about reachability:
 
 HTMLCollection::create: Does a collection own the node it is rooted in?
 MessageEvent::initMessageEvent: Does a message event own the source DOM 
 window?
 Range::create: Does a range own the document its nodes are in and the nodes 
 that are used to specify the endpoints?
 Storage::create: Does a storage object own its storage area?
 UIEvent::create: Does an event own its abstract view?

It seems to me that all of these objects become shared-owners of the respective 
parameter, in the sense of holding a persistent reference. Some don't literally 
stick it in a RefPtr but they do the moral equivalent.

 
 Here are some examples that are not purely DOM reachability that I find 
 confusing:
 
 Document::setTitleElement: Does a document own its title element?
 FrameLoaderClient::dispatchWillSubmitForm: Does communication of a pending 
 form submission involve passing ownership of form state?

Ditto.

Regards,
Maciej

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-20 Thread Alexey Proskuryakov

20.06.2011, в 03:22, Maciej Stachowiak написал(а):

 For a shared ownership model there are multiple possible definitions of 
 whether a function takes ownership to an object passed as an argument. Here 
 are some of my attempts to describe the bright line:
 
a) Hands off ownership to what could possibly be the sole owner in most 
 code paths.
b) Keeps a reference to the object after the function completes in most 
 code paths.
c) Takes a reference to the object at least once in most code paths.
 
d) Hands off ownership to what could possibly be the sole owner in some 
 code paths.
e) Keeps a reference to the object after it completes in some code paths.
f) Takes a reference to the object at least once in some code paths.
 
 Is the bright line rule you have in mind (b) or perhaps (e)? Or something 
 not listed here at all?
 
 Yes, (b) or (e). I haven't thought about whether most code paths or some 
 code paths makes more sense, but I'm not sure there are a lot of cases in 
 our code where it makes a difference.
 
 I don't think it makes sense to talk about a sole owner of a refcounted 
 object. If there is a sole owner at any given time, it is at best temporary. 
 PassRefPtr is about clearly and efficiently transferring a reference, it 
 doesn't need it to necessarily be the sole then-existing reference.

I think that to make this complete, the rules need to be transitive. A function 
that passes its argument to another function taking a PassRefPtr should itself 
take a PassRefPtr. That's the case in 
https://bugs.webkit.org/show_bug.cgi?id=52981, for instance.

It doesn't seem that analyzing code for most/some code paths takes ownership 
would be any easier that analyzing it for any caller gives away ownership. 
Yet it's the latter where PassRefPtr is beneficial. Why base the rule on 
something that's disconnected from actual benefit?

- WBR, Alexey Proskuryakov

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-20 Thread Ryosuke Niwa
On Mon, Jun 20, 2011 at 9:19 AM, Alexey Proskuryakov a...@webkit.org wrote:

 I think that to make this complete, the rules need to be transitive. A
 function that passes its argument to another function taking a PassRefPtr
 should itself take a PassRefPtr. That's the case in 
 https://bugs.webkit.org/show_bug.cgi?id=52981, for instance.


I agree.  Most of editing bugs come from breaking that transitive rule.

I even want it be enforced by some C++ idiom; e.g. replace all raw pointers
in argument list by PassRawPtr, which cannot be converted to PassRefPtr or
RefPtr.

- Ryosuke
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-20 Thread Maciej Stachowiak

On Jun 20, 2011, at 9:19 AM, Alexey Proskuryakov wrote:

 
 20.06.2011, в 03:22, Maciej Stachowiak написал(а):
 
 For a shared ownership model there are multiple possible definitions of 
 whether a function takes ownership to an object passed as an argument. Here 
 are some of my attempts to describe the bright line:
 
a) Hands off ownership to what could possibly be the sole owner in most 
 code paths.
b) Keeps a reference to the object after the function completes in most 
 code paths.
c) Takes a reference to the object at least once in most code paths.
 
d) Hands off ownership to what could possibly be the sole owner in some 
 code paths.
e) Keeps a reference to the object after it completes in some code paths.
f) Takes a reference to the object at least once in some code paths.
 
 Is the bright line rule you have in mind (b) or perhaps (e)? Or something 
 not listed here at all?
 
 Yes, (b) or (e). I haven't thought about whether most code paths or some 
 code paths makes more sense, but I'm not sure there are a lot of cases in 
 our code where it makes a difference.
 
 I don't think it makes sense to talk about a sole owner of a refcounted 
 object. If there is a sole owner at any given time, it is at best temporary. 
 PassRefPtr is about clearly and efficiently transferring a reference, it 
 doesn't need it to necessarily be the sole then-existing reference.
 
 I think that to make this complete, the rules need to be transitive. A 
 function that passes its argument to another function taking a PassRefPtr 
 should itself take a PassRefPtr. That's the case in 
 https://bugs.webkit.org/show_bug.cgi?id=52981, for instance.
 
 It doesn't seem that analyzing code for most/some code paths takes 
 ownership would be any easier that analyzing it for any caller gives away 
 ownership.

In general it only requires inspecting the source of the function, and possibly 
the signatures of function it calls. The analysis for any caller gives away 
ownership requires searching over all of WebCore to find possible call sites. 
And it can easily change

If we think the transitivity problem is a hazard, we could make PassRefPtr 
refuse to implicitly convert from raw pointers. Then to pass a raw pointer to a 
function that uses PassRefPtr you'd have to make a RefPtr first (or adopt, if 
the ref is unowned). That would make takes ownership analysis purely local to 
the function source. 

 Yet it's the latter where PassRefPtr is beneficial. Why base the rule on 
 something that's disconnected from actual benefit?

Because it's simpler to read the source of your own function than to visit all 
call sites, and it's more obvious that when you change what the function does 
you may need to change the signature.

Regards,
Macij

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-20 Thread David Levin
On Mon, Jun 20, 2011 at 5:25 PM, Maciej Stachowiak m...@apple.com wrote:


 On Jun 20, 2011, at 9:19 AM, Alexey Proskuryakov wrote:


 20.06.2011, в 03:22, Maciej Stachowiak написал(а):

 For a shared ownership model there are multiple possible definitions of
 whether a function takes ownership to an object passed as an argument. Here
 are some of my attempts to describe the bright line:

a) Hands off ownership to what could possibly be the sole owner in most
 code paths.
b) Keeps a reference to the object after the function completes in most
 code paths.
c) Takes a reference to the object at least once in most code paths.

d) Hands off ownership to what could possibly be the sole owner in some
 code paths.
e) Keeps a reference to the object after it completes in some code
 paths.
f) Takes a reference to the object at least once in some code paths.

 Is the bright line rule you have in mind (b) or perhaps (e)? Or something
 not listed here at all?


 Yes, (b) or (e). I haven't thought about whether most code paths or some
 code paths makes more sense, but I'm not sure there are a lot of cases in
 our code where it makes a difference.

 I don't think it makes sense to talk about a sole owner of a refcounted
 object. If there is a sole owner at any given time, it is at best temporary.
 PassRefPtr is about clearly and efficiently transferring a reference, it
 doesn't need it to necessarily be the sole then-existing reference.


 I think that to make this complete, the rules need to be transitive. A
 function that passes its argument to another function taking a PassRefPtr
 should itself take a PassRefPtr. That's the case in 
 https://bugs.webkit.org/show_bug.cgi?id=52981, for instance.

 It doesn't seem that analyzing code for most/some code paths takes
 ownership would be any easier that analyzing it for any caller gives away
 ownership.


 In general it only requires inspecting the source of the function, and
 possibly the signatures of function it calls. The analysis for any caller
 gives away ownership requires searching over all of WebCore to find
 possible call sites. And it can easily change

 If we think the transitivity problem is a hazard, we could make PassRefPtr
 refuse to implicitly convert from raw pointers. Then to pass a raw pointer
 to a function that uses PassRefPtr you'd have to make a RefPtr first (or
 adopt, if the ref is unowned). That would make takes ownership analysis
 purely local to the function source.


I thought the problem was that a Pass*Ptr could silently 0 itself out and
people use it directly.

So the real problem functions are anything the fact that a Pass*Ptr can be
used like a pointer and that another Pass*Ptr can slurp out its contents so
easily (and you can't spot this in the code well).

Maybe each of those operations should be more explicit? (Then we could
probably even catch these issues automatically. If *.passPtr() is called and
then *.get() is called later in the same function, mark it as an error. Not
perfect but good enough.)



 Yet it's the latter where PassRefPtr is beneficial. Why base the rule on
 something that's disconnected from actual benefit?


 Because it's simpler to read the source of your own function than to visit
 all call sites, and it's more obvious that when you change what the function
 does you may need to change the signature.


This seems much easier, less error prone, and more stable.

dave


 Regards,
 Macij


 ___
 webkit-dev mailing list
 webkit-dev@lists.webkit.org
 http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-20 Thread Alexey Proskuryakov

20.06.2011, в 17:25, Maciej Stachowiak написал(а):

 Yet it's the latter where PassRefPtr is beneficial. Why base the rule on 
 something that's disconnected from actual benefit?
 
 Because it's simpler to read the source of your own function than to visit 
 all call sites, and it's more obvious that when you change what the function 
 does you may need to change the signature.

I do not see how you are describing a practical coding situation here. I do not 
start with a dozen call sites all over the code base, and then write a function 
they all call. On the other hand, when adding a new call site that wants to 
pass ownership away, and the called function doesn't take a PassRefPtr, it's 
immediately obvious that it's not going to work.

Even when following a cargo cult rule is easier (not uncommon!), the problem of 
it being disconnected from the actual benefit still remains.

- WBR, Alexey Proskuryakov

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-20 Thread David Levin
On Mon, Jun 20, 2011 at 6:11 PM, Alexey Proskuryakov a...@webkit.org wrote:


 20.06.2011, в 17:25, Maciej Stachowiak написал(а):

  Yet it's the latter where PassRefPtr is beneficial. Why base the rule on
 something that's disconnected from actual benefit?
 
  Because it's simpler to read the source of your own function than to
 visit all call sites, and it's more obvious that when you change what the
 function does you may need to change the signature.

 I do not see how you are describing a practical coding situation here. I do
 not start with a dozen call sites all over the code base, and then write a
 function they all call. On the other hand, when adding a new call site that
 wants to pass ownership away, and the called function doesn't take a
 PassRefPtr, it's immediately obvious that it's not going to work.

 Even when following a cargo cult rule is easier (not uncommon!), the
 problem of it being disconnected from the actual benefit still remains.


Here's a few benefits:
1. It makes the code more self-documenting. It clearly indicates that this
function intends to take a reference to the item.
2. It is consistent with the rules for PassOwnPtr. It is nice to have one
set of things in mind that are consistent.
3. Just like one shouldn't document a function based on who calls it because
that may change, it makes sense to base the argument types on the how the
function uses them not on the callers.




 - WBR, Alexey Proskuryakov

 ___
 webkit-dev mailing list
 webkit-dev@lists.webkit.org
 http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-20 Thread Alexey Proskuryakov

20.06.2011, в 21:29, David Levin написал(а):

 Here's a few benefits:
 1. It makes the code more self-documenting. It clearly indicates that this 
 function intends to take a reference to the item.
 2. It is consistent with the rules for PassOwnPtr. It is nice to have one set 
 of things in mind that are consistent.
 3. Just like one shouldn't document a function based on who calls it because 
 that may change, it makes sense to base the argument types on the how the 
 function uses them not on the callers.

1 and 3 sound very closely related. Yet I'm not sure if they are good.

PassRefPtr is useful even if the function doesn't take any kind of ownership. 
It's useful when callers want to get rid of ownership, and then they can do 
that efficiently.

As Maciej mentioned, eventually we may be able to get rid of PassRefPtr, and 
use C++0x move semantics. But applicability of move semantics also depends on 
how a function is called, not on what it is going to do with its arguments.

- WBR, Alexey Proskuryakov

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-20 Thread David Levin
On Mon, Jun 20, 2011 at 9:39 PM, Alexey Proskuryakov a...@webkit.org wrote:


 20.06.2011, в 21:29, David Levin написал(а):

  Here's a few benefits:
  1. It makes the code more self-documenting. It clearly indicates that
 this function intends to take a reference to the item.
  2. It is consistent with the rules for PassOwnPtr. It is nice to have one
 set of things in mind that are consistent.
  3. Just like one shouldn't document a function based on who calls it
 because that may change, it makes sense to base the argument types on the
 how the function uses them not on the callers.

 1 and 3 sound very closely related. Yet I'm not sure if they are good.


True, I didn't think of it that way when I wrote it. :) I feel like they are
good, but I could be wrong. (I always have felt like knowing who is owning
something is one of those tricky things when reading code so I've
appreciated this but it may be of limited value when taking about ref
counted items.)

And I like 2 but it isn't critical.



 PassRefPtr is useful even if the function doesn't take any kind of
 ownership. It's useful when callers want to get rid of ownership, and then
 they can do that efficiently.


I don't understand this. How it is more efficient to pass ownership if a
function isn't taking ownership? It seems like passing in a raw pointer
would be the most efficient in this case.


 As Maciej mentioned, eventually we may be able to get rid of PassRefPtr,
 and use C++0x move semantics. But applicability of move semantics also
 depends on how a function is called, not on what it is going to do with its
 arguments.


Good point. Makes sense.

dave



 - WBR, Alexey Proskuryakov

 ___
 webkit-dev mailing list
 webkit-dev@lists.webkit.org
 http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-19 Thread Darin Adler
The arguments about abandoning PassRefPtr for arguments entirely are attacking 
a straw man. We know PassRefPtr offers an important optimization and do not 
want to drop that!

On Jun 18, 2011, at 10:58 PM, Maciej Stachowiak wrote:

 (1) Use PassRefPtr for every parameter that takes ownership.

I still think this is the appropriate rule, and always have, but I think “takes 
ownership” is not defined to my satisfaction.

 Pro (of using PassRefPtr for every parameter that takes ownership):
Bright-line rule; fairly clear how to apply it.

This is where my problem comes in. I am not sure what the bright-line rule is.

Generally, in the DOM, the rule is that all reachable objects need to be kept 
alive, so reference counting is used to implement reachability, which does not 
match with my sense of the word ownership.

For a shared ownership model there are multiple possible definitions of whether 
a function takes ownership to an object passed as an argument. Here are some of 
my attempts to describe the bright line:

a) Hands off ownership to what could possibly be the sole owner in most 
code paths.
b) Keeps a reference to the object after the function completes in most 
code paths.
c) Takes a reference to the object at least once in most code paths.

d) Hands off ownership to what could possibly be the sole owner in some 
code paths.
e) Keeps a reference to the object after it completes in some code paths.
f) Takes a reference to the object at least once in some code paths.

Is the bright line rule you have in mind (b) or perhaps (e)? Or something not 
listed here at all?

Editing operations that are undoable often meet (b) but not (a). It’s confusing 
to me that editing operations want to “take ownership” of arguments. To make 
editing undoable the undo machinery may have to reference these objects, but it 
may also have to reference objects as well, perhaps the document or other 
elements. It’s not clear to me that requesting editing by passing arguments 
that specify where in the document the edit should take place means that the 
function takes ownership of those arguments.

If we tell the document which is the currently active title element by calling 
setTitleElement, the function meets (b) but not (a).

Similarly, some functions call out to operations that could cause the last 
owner for one of their arguments to dereference the object. They are likely to 
fit into category (c) or (f). In a sense the caller does have to pass ownership 
of the object, because the operation can only be successfully done if the 
function takes ownership to make sure the object does not disappear while the 
code is working with it.

 Con (of using PassRefPtr for every parameter that takes ownership):
Possible accidental self-zeroing bugs.

I think the “possible” adjective here makes this sound like a smaller problem 
than it is. Alexey and I have both seen multiple examples of this, particularly 
in contexts like constructor initialization lists where the prp idiom does not 
work well.

 Con (of abandoning PassRefPtr for function arguments entirely):

 Possible accidental freed memory access bugs.


I think the reverse of this Con is one of the stronger Pro arguments for using 
PassRefPtr even more for arguments rather than my proposal to use it less. 
Object lifetime mistakes are much less likely when raw pointers are kept to an 
absolute minimum. I thought about this when reviewing the design of Automatic 
Reference Counting. The ARC design largely eliminates raw pointers for 
Objective-C objects.

I tried to find the examples that bother me. Here are some DOM examples where 
the term ownership seems wrong, and it’s more about reachability:

HTMLCollection::create: Does a collection own the node it is rooted in?
MessageEvent::initMessageEvent: Does a message event own the source DOM window?
Range::create: Does a range own the document its nodes are in and the nodes 
that are used to specify the endpoints?
Storage::create: Does a storage object own its storage area?
UIEvent::create: Does an event own its abstract view?

Here are some examples that are not purely DOM reachability that I find 
confusing:

Document::setTitleElement: Does a document own its title element?
FrameLoaderClient::dispatchWillSubmitForm: Does communication of a pending form 
submission involve passing ownership of form state?

I couldn’t quickly find other examples, but I have a vague sense that there are 
some that are even more confusing.

-- Darin

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-19 Thread Ryosuke Niwa
On Sun, Jun 19, 2011 at 12:48 PM, Darin Adler da...@apple.com wrote:

  Con (of abandoning PassRefPtr for function arguments entirely):

  Possible accidental freed memory access bugs.

 I think the reverse of this Con is one of the stronger Pro arguments for
 using PassRefPtr even more for arguments rather than my proposal to use it
 less. Object lifetime mistakes are much less likely when raw pointers are
 kept to an absolute minimum. I thought about this when reviewing the design
 of Automatic Reference Counting. The ARC design largely eliminates raw
 pointers for Objective-C objects.


One of the most common security bugs I have seen in editing is that we keep
a raw pointer to a node and call some helper method that modifies DOM
(therefore invoking scripts).

I'm sometimes tempted to replace all instances of Node* in the editing
component by RefPtr/PassRefPtr.

- Ryosuke
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-19 Thread Darin Adler
On Jun 19, 2011, at 2:03 PM, Ryosuke Niwa wrote:

 One of the most common security bugs I have seen in editing is that we keep a 
 raw pointer to a node and call some helper method that modifies DOM 
 (therefore invoking scripts).
 
 I'm sometimes tempted to replace all instances of Node* in the editing 
 component by RefPtr/PassRefPtr.

I suspect that if the data members and local variables had type RefPtr, then it 
mostly wouldn’t matter if argument types were PassRefPtr or raw pointers for 
this purpose.

-- Darin

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-19 Thread Ryosuke Niwa
On Sun, Jun 19, 2011 at 2:05 PM, Darin Adler da...@apple.com wrote:

 On Jun 19, 2011, at 2:03 PM, Ryosuke Niwa wrote:

  One of the most common security bugs I have seen in editing is that we
 keep a raw pointer to a node and call some helper method that modifies DOM
 (therefore invoking scripts).
 
  I'm sometimes tempted to replace all instances of Node* in the editing
 component by RefPtr/PassRefPtr.

 I suspect that if the data members and local variables had type RefPtr,
 then it mostly wouldn’t matter if argument types were PassRefPtr or raw
 pointers for this purpose.


Right, although it's tricky to catch cases where we call a function that
takes multiple arguments (one of them being Node*) with the return value of
a function that modifies DOM.

- Ryosuke
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


[webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-18 Thread Darin Adler
1:

Recently, Alexey has encouraged me to use PassRefPtr less for function 
arguments.

The PassRefPtr optimization pays off when the object in question is possibly 
being handed off from one PassRefPtr to another. For an argument, that can 
happen in two ways: 1) The argument can be the result of a function that 
returns a PassRefPtr. 2) The argument can be the result of calling release a 
local or data member that is a RefPtr. In both of those cases, we are 
transferring ownership.

Mechanically speaking, PassRefPtr only pays off if we are actually getting that 
optimization. If we are passing a raw pointer, then using PassRefPtr for the 
function argument type doesn’t help much. It just puts a ref at the call site, 
a ref that otherwise would happen inside the function. It may even cause a bit 
of code bloat if there is more than one call site.

Conceptually speaking, PassRefPtr only pays off if the context is a clear 
transfer of ownership. Passing an object that the recipient *might* later 
choose to take shared ownership of is not enough. Clients are always welcome to 
take shared ownership of something passed with a raw pointer.

Because there are also costs to PassRefPtr, we should reserve PassRefPtr 
arguments for cases where the optimization will really pay off and for where 
the function definitely is taking ownership. Those functions do exist, but many 
current uses of PassRefPtr for arguments do not qualify.

2:

Recently, I’ve noticed that many bugs simply would cease to exist if we used 
RefPtr more and raw pointer less for things like local variables and data 
members.

The time it’s safe to use a raw pointer for a local variable or data member for 
a reference counted object pointer is when there is some guarantee that someone 
else is holding a reference. It can be difficult to have such a guarantee and 
those guarantees are fragile as code executes. Nowhere is that more clear than 
in loader-related code.

Some are loathe to use RefPtr for data members because they are concerned about 
reference cycles. Generally speaking, we can eliminate the worry about 
reference cycles by making destruction include a “closing” process, which can 
null out all the references and break cycles. If we find it’s necessary we can 
also look into an efficient WeakPtr implementation. Some have been enthusiastic 
about this in the past. I have been a bit less so because I don’t know of an 
efficient implementation strategy.

Conclusion:

A specific example where an argument has type PassRefPtr, but that does not 
seem like the correct design, is the the node argument in the constructors of 
the various HTMLCollection classes.

Examples of where we are using raw pointers, but should use RefPtr instead 
abound. Sadly there is no way to qualify a member function to make “this” a 
RefPtr, so we are stuck with the “protector” idiom for the this pointer.

Maybe we can even find a way to discuss these two issues in the RefPtr document 
without making it too confusing.

Comments are welcome. But lets not bikeshed 
http://en.wikipedia.org/wiki/Parkinson's_Law_of_Triviality this!

-- Darin

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-18 Thread Adam Barth
I've fixed many a security bug cause by not refing local variables.
Generally, you need to ref your local variables if any function you call can
end up executing JavaScript (and many can).  If you're not sure, please feel
encouraged to ask around.

Adam
 On Jun 18, 2011 8:54 PM, Darin Adler da...@apple.com wrote:
 1:

 Recently, Alexey has encouraged me to use PassRefPtr less for function
arguments.

 The PassRefPtr optimization pays off when the object in question is
possibly being handed off from one PassRefPtr to another. For an argument,
that can happen in two ways: 1) The argument can be the result of a function
that returns a PassRefPtr. 2) The argument can be the result of calling
release a local or data member that is a RefPtr. In both of those cases, we
are transferring ownership.

 Mechanically speaking, PassRefPtr only pays off if we are actually getting
that optimization. If we are passing a raw pointer, then using PassRefPtr
for the function argument type doesn’t help much. It just puts a ref at the
call site, a ref that otherwise would happen inside the function. It may
even cause a bit of code bloat if there is more than one call site.

 Conceptually speaking, PassRefPtr only pays off if the context is a clear
transfer of ownership. Passing an object that the recipient *might* later
choose to take shared ownership of is not enough. Clients are always welcome
to take shared ownership of something passed with a raw pointer.

 Because there are also costs to PassRefPtr, we should reserve PassRefPtr
arguments for cases where the optimization will really pay off and for where
the function definitely is taking ownership. Those functions do exist, but
many current uses of PassRefPtr for arguments do not qualify.

 2:

 Recently, I’ve noticed that many bugs simply would cease to exist if we
used RefPtr more and raw pointer less for things like local variables and
data members.

 The time it’s safe to use a raw pointer for a local variable or data
member for a reference counted object pointer is when there is some
guarantee that someone else is holding a reference. It can be difficult to
have such a guarantee and those guarantees are fragile as code executes.
Nowhere is that more clear than in loader-related code.

 Some are loathe to use RefPtr for data members because they are concerned
about reference cycles. Generally speaking, we can eliminate the worry about
reference cycles by making destruction include a “closing” process, which
can null out all the references and break cycles. If we find it’s necessary
we can also look into an efficient WeakPtr implementation. Some have been
enthusiastic about this in the past. I have been a bit less so because I
don’t know of an efficient implementation strategy.

 Conclusion:

 A specific example where an argument has type PassRefPtr, but that does
not seem like the correct design, is the the node argument in the
constructors of the various HTMLCollection classes.

 Examples of where we are using raw pointers, but should use RefPtr instead
abound. Sadly there is no way to qualify a member function to make “this” a
RefPtr, so we are stuck with the “protector” idiom for the this pointer.

 Maybe we can even find a way to discuss these two issues in the RefPtr
document without making it too confusing.

 Comments are welcome. But lets not bikeshed 
http://en.wikipedia.org/wiki/Parkinson's_Law_of_Triviality this!

 -- Darin

 ___
 webkit-dev mailing list
 webkit-dev@lists.webkit.org
 http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-18 Thread Maciej Stachowiak

On Jun 18, 2011, at 5:52 PM, Darin Adler wrote:

 1:
 
 Recently, Alexey has encouraged me to use PassRefPtr less for function 
 arguments.
 
 The PassRefPtr optimization pays off when the object in question is possibly 
 being handed off from one PassRefPtr to another. For an argument, that can 
 happen in two ways: 1) The argument can be the result of a function that 
 returns a PassRefPtr. 2) The argument can be the result of calling release a 
 local or data member that is a RefPtr. In both of those cases, we are 
 transferring ownership.
 
 Mechanically speaking, PassRefPtr only pays off if we are actually getting 
 that optimization. If we are passing a raw pointer, then using PassRefPtr for 
 the function argument type doesn’t help much. It just puts a ref at the call 
 site, a ref that otherwise would happen inside the function. It may even 
 cause a bit of code bloat if there is more than one call site.
 
 Conceptually speaking, PassRefPtr only pays off if the context is a clear 
 transfer of ownership. Passing an object that the recipient *might* later 
 choose to take shared ownership of is not enough. Clients are always welcome 
 to take shared ownership of something passed with a raw pointer.
 
 Because there are also costs to PassRefPtr, we should reserve PassRefPtr 
 arguments for cases where the optimization will really pay off and for where 
 the function definitely is taking ownership. Those functions do exist, but 
 many current uses of PassRefPtr for arguments do not qualify.

A few thoughts on this:

- The benefit of PassRefPtr at any individual call site is probably too small 
to be measurable, but I believe taken together they all add up to somewhere in 
the ballpark of .2%-.5% on some benchmarks by avoiding refcount churn.

- I think having a rule for using PassRefPtr for arguments that depends on how 
callers use the function is likely to be hard to use in practice, since it 
requires global knowledge of all callers to pick the right function signature. 
The rule I prefer is that if a function takes ownership of the argument, 
whether or not we currently have a caller that gives away ownership, the 
function should take PassRefPtr. If it does not take ownership, it should take 
a raw pointer. That way you can decide the right thing to do based solely on 
the definition of the function itself.

- Longer term we can replace PassRefPtr with use of C++0x rvalue references. I 
wonder if it's possible to do this in a way where we use rvalue references on 
compilers that support them and classic PassRefPtr elsewhere.

 
 2:
 
 Recently, I’ve noticed that many bugs simply would cease to exist if we used 
 RefPtr more and raw pointer less for things like local variables and data 
 members.
 
 The time it’s safe to use a raw pointer for a local variable or data member 
 for a reference counted object pointer is when there is some guarantee that 
 someone else is holding a reference. It can be difficult to have such a 
 guarantee and those guarantees are fragile as code executes. Nowhere is that 
 more clear than in loader-related code.
 
 Some are loathe to use RefPtr for data members because they are concerned 
 about reference cycles. Generally speaking, we can eliminate the worry about 
 reference cycles by making destruction include a “closing” process, which can 
 null out all the references and break cycles. If we find it’s necessary we 
 can also look into an efficient WeakPtr implementation. Some have been 
 enthusiastic about this in the past. I have been a bit less so because I 
 don’t know of an efficient implementation strategy.

We could probably use RefPtr for at least some data members in the DOM, but it 
would be tricky to avoid introducing needless refcount churn. I guess this gets 
back to the point about PassRefPtr.

Using RefPtr for locals is probably a good idea in some cases, but it can also 
lead to refcount churn, and refcount churn tends to make a program slower by 
death of a thousand cuts, so it's hard to find the source of the problem after 
the fact. I've wondered at times whether it might be a good idea to use a 
RefPtrT (note the reference) for cases where it's desirable to be guaranteed 
that someone holds a ref but you don't want to add an extra ref yourself.

 Conclusion:
 
 A specific example where an argument has type PassRefPtr, but that does not 
 seem like the correct design, is the the node argument in the constructors of 
 the various HTMLCollection classes.

That's probably so, but I'd also guess the cost is smaller than maintaining 
clear understanding of why PassRefPtr should not be used here but should in 
other similar cases. i would still prefer to adhere to the simpler rule even 
though PassRefPtr doesn't add anything in this specific case.

PassRefPtr also makes it harder to accidentally put an incoming pointer into a 
raw pointer data member or local variable, so it has a potential typechecking 
benefit even when it isn't helping your 

Re: [webkit-dev] Lets use PassRefPtr for arguments less; lets use RefPtr for locals and data members more

2011-06-18 Thread Alexey Proskuryakov

18.06.2011, в 22:15, Maciej Stachowiak написал(а):

 - I think having a rule for using PassRefPtr for arguments that depends on 
 how callers use the function is likely to be hard to use in practice, since 
 it requires global knowledge of all callers to pick the right function 
 signature. The rule I prefer is that if a function takes ownership of the 
 argument, whether or not we currently have a caller that gives away 
 ownership, the function should take PassRefPtr. If it does not take 
 ownership, it should take a raw pointer. That way you can decide the right 
 thing to do based solely on the definition of the function itself.


Using PassRefPtr for arguments is a fairly common source of bugs. The way it's 
zeroed out after being used has caused crashes in code paths that weren't 
tested before commit for some reason (see e.g. 
https://bugs.webkit.org/show_bug.cgi?id=52981). Another example that we've 
just seen (https://bugs.webkit.org/show_bug.cgi?id=62836) was when a 
different compiler had a different order of evaluation, so building with it 
suddenly exposed a crash that we didn't need to have.

Looking at either bug, using PassRefPtr is pointless. For trace(), we could 
theoretically pass ownership from jsConsolePrototypeFunctionTrace(), but we do 
not, and micro-optimizing Console functions for performance isn't worth the 
cost of having had this crasher bug in my opinion. For bug 62836, it's quite 
clearly impossible to pass ownership to HTMLTableRowsCollection.

- WBR, Alexey Proskuryakov

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev