[webkit-dev] New smart pointers for efficient refcounting
Maciej Stachowiak
mjs at apple.com
Tue Nov 29 20:24:50 PST 2005
Hi everyone,
In many places, to get memory management right, it is way more
convenient and less error-prone to use a smart pointer, like SharedPtr
(*). However, sometimes this leads to needless thrashing of the
refcount. For example, any function that returns a newly created
refcounted object should really give you a SharedPtr, to avoid
leaking. But suppose that value is going to go directly into a data
member that is a SharedPtr. That's going to lead to an extra ref and
deref. In some spots that actually shows up on the profile. With
manual refcounting you can special-case taking ownership of a newly
created object, and avoid the extra ref and deref.
I came up with a simple idea for how to deploy smart pointers
throughout without suffering from this refcount thrash. It is
inspired by the standard C++ library's auto_ptr.
The basic idea is that you keep SharedPtr for most purposes; but in
interfaces where you pass ownership, you use the new PassRefPtr.
Passing ownership means either returning a newly allocated object (or
otherwise one that the callee won't hold onto), or passing in as an
argument an object the function is guaranteed to ref and hold onto.
PassRefPtr works just like SharedPtr in most respects, except for
assignment semantics:
SharedPtr = SharedPtr // both keep a ref
PassRefPtr = SharedPtr // both keep a ref
SharedPtr = PassRefPtr // PassRefPtr transfers ownership and nils
itself out
PassRefPtr = PassRefPtr // second PassRefPtr transfers ownership and
nils itself out
Then you follow these rules:
- local variables, global variables and data members should be a
SharedPtr if they maintain a referece, or a raw pointer if they don't
need to (for example a parent pointer, where the parent owns you)
- function return values and parameters should be a raw pointer or a
PassRefPtr (not a PassRefPtr& or const PassRefPtr&), depending on
whether they transfer ownership
- sometimes you might want to use a PassRefPtr for a local variable,
if you plan to immediately transfer ownership
Here's a test program I made that includes the PassRefPtr
implementation and demonstrates use. A function getRefCounter returns
a PassRefPtr which is then passed off to an Acceptor object's
constructor.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: reftest.cpp
Type: application/octet-stream
Size: 6559 bytes
Desc: not available
Url : http://lists.macosforge.org/pipermail/webkit-dev/attachments/20051129/cf32156d/reftest.obj
-------------- next part --------------
This runs in 2.95 seconds compared to 3.05 for this naiive SharedPtr
version:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: reftest2.cpp
Type: application/octet-stream
Size: 6556 bytes
Desc: not available
Url : http://lists.macosforge.org/pipermail/webkit-dev/attachments/20051129/cf32156d/reftest2.obj
-------------- next part --------------
So it's a measurable speedup to save those extra refs and derefs at
construction time.
I plan to integrate this soon. Any thoughts?
Regards,
Maciej
* - I'd also like to rename SharedPtr to RefPtr and Shared to
RefCounted, but I'm gonna stick with the SharedPtr terminology for
this email.
More information about the webkit-dev
mailing list