This patch adds smart pointers to be used for initializing objects as C++11
"magic statics" -- that is, they are able to take advantage of C++11's
guarantee of thread safety during initialization by atomically constructing
both the smart pointer itself as well as the object being pointed to.
Unlike Static{Auto,Ref}Ptr, they have non-trivial constructors, though they
must still have trivial destructors to prevent emission of atexit calls.
The new classes use the new `MOZ_STATIC_LOCAL_CLASS` annotation which ensures
their instantiations are static locals and prevents non-trivial destructors.
Differential Revision: https://phabricator.services.mozilla.com/D40092
--HG--
rename : xpcom/base/StaticPtr.h => xpcom/base/StaticLocalPtr.h
extra : moz-landing-system : lando
I'd like to add a constructor and operator= to RefPtr for mscom::AgileReference.
This patch is simply the forward declarations to allow for that.
Differential Revision: https://phabricator.services.mozilla.com/D5317
--HG--
extra : moz-landing-system : lando
I'd like to add a constructor and operator= to RefPtr for mscom::AgileReference.
This patch is simply the forward declarations to allow for that.
Differential Revision: https://phabricator.services.mozilla.com/D5317
--HG--
extra : source : 2787fb454f40584ad146c61fd9b375c419efe803
I'd like to add a constructor and operator= to RefPtr for mscom::AgileReference.
This patch is simply the forward declarations to allow for that.
Differential Revision: https://phabricator.services.mozilla.com/D5317
--HG--
extra : moz-landing-system : lando
I'd like to add a constructor and operator= to RefPtr for mscom::AgileReference.
This patch is simply the forward declarations to allow for that.
Differential Revision: https://phabricator.services.mozilla.com/D5317
--HG--
extra : moz-landing-system : lando
Same approach as the other bug, mostly replacing automatically by removing
'using mozilla::Forward;' and then:
s/mozilla::Forward/std::forward/
s/Forward</std::forward</
The only file that required manual fixup was TestTreeTraversal.cpp, which had
a class called TestNodeForward with template parameters :)
MozReview-Commit-ID: A88qFG5AccP
When we use RefPtr with nsISupports sub-classes, it's usually because the type
cannot be unambiguously cast to nsISupports. We already have a ToSupports
generic function to resolve ambiguity in these cases, so we may as well use
it here.
MozReview-Commit-ID: FaHhPKAPn6j
--HG--
extra : rebase_source : dd8f3707bdebedfe559aed0caf2c3b0c49163735
extra : histedit_source : 9805787a169329b9c739dfa456cfe6a61a22b7d7
nsQueryReferent is defined as an nsCOMPtr_helper, which implies that
calling its operator() method requires a virtual call. While
nsQueryReferent is marked `final`, compiler inlining decisions make it
impossible to de-virtualize the call to operator(). However, we have
many other classes returned by do_* functions that nsCOMPtr handles
directly, requiring no extra virtual calls, and we can give
nsQueryReferent the same treatment.
Making this constructor non-explicit will permit automatic conversions from
'nullptr' into RefPtr types, which I think are not dangerous.
The one spot that this affects is in 'UserDataType nsBaseHashtable::Get(KeyType)',
which does a 'return 0;' into the UserDataType, which could be a bool, an int, a
RefPtr or other. I'm changing that into a C++11 "value initialization", which
falls back to "zero initialization" for PODs: 'return UserDataType{};'.
Also fixed the comment to clarify not-found return values, as Get(KeyType) was
not only used for pointers anyway.
MozReview-Commit-ID: F41VlvTNOZU
--HG--
extra : rebase_source : 71d5dacac75ca188e5c55d45f48a5fca76d953c6
Added constructor and operator= from a nullptr, bypassing the incoming pointer
check.
Note that the constructor is 'explicit', because one particular use in
nsBaseHashtable is doing a 'return 0' into a templated type that is a RefPtr in
many cases. Making this new constructor explicit removes it from consideration
in this case.
As it's not strictly necessary to have it MOZ_IMPLICIT (but could still be
nice), I will tackle that in the patch after next.
Also changed all zeroes into nullptr when relevant in RefPtr.h (other system-
wide affected files will be updated in following patch.)
MozReview-Commit-ID: Ds4CEv9hZWI
--HG--
extra : rebase_source : f4ec156b13ea3bdcf32b1a33d76ff9771ad6d1dc
This means we can return already_AddRefed<T> for any RefPtr<T>s
being held as instance variables easier.
MozReview-Commit-ID: HFHdkF8EUsK
--HG--
extra : rebase_source : df650d39c010386afcb8cb2dd48292c26fbc6501
The bulk of this commit was generated with a script, executed at the top
level of a typical source code checkout. The only non-machine-generated
part was modifying MFBT's moz.build to reflect the new naming.
CLOSED TREE makes big refactorings like this a piece of cake.
# The main substitution.
find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \
xargs perl -p -i -e '
s/nsRefPtr\.h/RefPtr\.h/g; # handle includes
s/nsRefPtr ?</RefPtr</g; # handle declarations and variables
'
# Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h.
perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h
# Handle nsRefPtr.h itself, a couple places that define constructors
# from nsRefPtr, and code generators specially. We do this here, rather
# than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename
# things like nsRefPtrHashtable.
perl -p -i -e 's/nsRefPtr/RefPtr/g' \
mfbt/nsRefPtr.h \
xpcom/glue/nsCOMPtr.h \
xpcom/base/OwningNonNull.h \
ipc/ipdl/ipdl/lower.py \
ipc/ipdl/ipdl/builtin.py \
dom/bindings/Codegen.py \
python/lldbutils/lldbutils/utils.py
# In our indiscriminate substitution above, we renamed
# nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up.
find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \
xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g'
if [ -d .git ]; then
git mv mfbt/nsRefPtr.h mfbt/RefPtr.h
else
hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h
fi
--HG--
rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
This commit was generated using the following script, executed at the
top level of a typical source code checkout.
# Don't modify select files in mfbt/ because it's not worth trying to
# tease out the dependencies currently.
#
# Don't modify anything in media/gmp-clearkey/0.1/ because those files
# use their own RefPtr, defined in their own RefCounted.h.
find . -name '*.cpp' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \
grep -v 'mfbt/RefPtr.h' | \
grep -v 'mfbt/nsRefPtr.h' | \
grep -v 'mfbt/RefCounted.h' | \
grep -v 'media/gmp-clearkey/0.1/' | \
xargs perl -p -i -e '
s/mozilla::RefPtr/nsRefPtr/g; # handle declarations in headers
s/\bRefPtr</nsRefPtr</g; # handle local variables in functions
s#mozilla/RefPtr.h#mozilla/nsRefPtr.h#; # handle #includes
s#mfbt/RefPtr.h#mfbt/nsRefPtr.h#; # handle strange #includes
'
# |using mozilla::RefPtr;| is OK; |using nsRefPtr;| is invalid syntax.
find . -name '*.cpp' -o -name '*.mm' | xargs sed -i -e '/using nsRefPtr/d'
# RefPtr.h used |byRef| for dealing with COM-style outparams.
# nsRefPtr.h uses |getter_AddRefs|.
# Fixup that mismatch.
find . -name '*.cpp' -o -name '*.h'| \
xargs perl -p -i -e 's/byRef/getter_AddRefs/g'
A number of places depend on RefPtr.h providing this function. When we
s/RefPtr/nsRefPtr/, such places still need to be able to see this
function. Moving it to nsRefPtr.h makes it still visible before we
switch (since RefPtr.h includes nsRefPtr.h), and after we switch (since
every place that #includes RefPtr.h will now be #including nsRefPtr.h).
Various bits depend on RefPtr.h to provide RefCounted<T> and RefPtr<T>.
It will be easier to manage an automatic conversion from RefPtr<T> to
nsRefPtr<T> if we split out the dependency on RefCounted<T> first.
I put MOZ_HAVE_REF_QUALIFIERS in Attributes.h for lack of a better
place. I didn't especially want to make a whole new file for it.
To make the tree compile, support for moving RefPtr to nsRefPtr was
needed. I chose to put the definitions in RefPtr.h instead of
nsRefPtr.h because RefPtr.h looks to be included in fewer files, so I
preferred to bloat fewer files with the extra include.
For some reason operator!() wasn't necessary here, although it seems it
is for nsRefPtr.
This conversion was done with the script:
find . -name '*.cpp' -o -name '*.h' -o -name '*.mm' -o -name '*.idl' | \
egrep -v 'cairo-win32-refptr.h|RefPtr.h|TestRefPtr.cpp' | \
xargs sed -i -e 's/mozilla::TemporaryRef</already_AddRefed</g' \
-e 's/TemporaryRef</already_AddRefed</g'
Manual fixups were performed in the following instances:
- We handled mfbt/RefPtr.h manually so as to not convert TemporaryRef itself
into already_AddRefed.
- The following files had explicit Move() calls added to make up for the lack
of a copy constructor on already_AddRefed:
dom/base/ImageEncoder.cpp
dom/media/MediaTaskQueue.{h,cpp}
dom/media/webaudio/PannerNode.cpp
- A redundant overload for MediaTaskQueue::Dispatch was deleted.
- A few manual fixups were required in mfbt/tests/TestRefPtr.cpp.
- Comments, using declarations, and forward declarations relating to
TemporaryRef in dom/canvas/ and gfx/layers/ were changed to refer to
already_AddRefed.
Having this implicit conversion means that we can silently do extra
refcounting when it's completely unnecessary. It's also an obstacle to
making RefPtr more nsRefPtr-like, so let's get rid of it.
With implicit conversion to TemporaryRef going away, one can no longer write:
return new T(...);
in a function returning TemporaryRef<T>. Instead, provide MakeAndAddRef
to prevent people from having to construct boilerplate RefPtrs or
similar. It also makes converting from TemporaryRef to already_AddRefed
somewhat easier.