mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1390568 - manually de-virtualize do_QueryReferent; r=ehsan
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.
This commit is contained in:
parent
519e4af9fe
commit
c5fa35746e
@ -15,6 +15,7 @@
|
||||
|
||||
// template <class T> class RefPtrGetterAddRefs;
|
||||
|
||||
class nsQueryReferent;
|
||||
class nsCOMPtr_helper;
|
||||
|
||||
namespace mozilla {
|
||||
@ -148,6 +149,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_IMPLICIT RefPtr(const nsQueryReferent& aHelper);
|
||||
MOZ_IMPLICIT RefPtr(const nsCOMPtr_helper& aHelper);
|
||||
|
||||
// Defined in OwningNonNull.h
|
||||
@ -210,6 +212,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
RefPtr<T>& operator=(const nsQueryReferent& aQueryReferent);
|
||||
RefPtr<T>& operator=(const nsCOMPtr_helper& aHelper);
|
||||
|
||||
RefPtr<T>&
|
||||
|
@ -109,6 +109,17 @@ nsCOMPtr_base::assign_from_gs_contractid_with_error(
|
||||
assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
|
||||
}
|
||||
|
||||
void
|
||||
nsCOMPtr_base::assign_from_query_referent(
|
||||
const nsQueryReferent& aQueryReferent, const nsIID& aIID)
|
||||
{
|
||||
void* newRawPtr;
|
||||
if (NS_FAILED(aQueryReferent(aIID, &newRawPtr))) {
|
||||
newRawPtr = nullptr;
|
||||
}
|
||||
assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
|
||||
}
|
||||
|
||||
void
|
||||
nsCOMPtr_base::assign_from_helper(const nsCOMPtr_helper& aHelper,
|
||||
const nsIID& aIID)
|
||||
|
@ -273,6 +273,25 @@ private:
|
||||
nsresult* mErrorPtr;
|
||||
};
|
||||
|
||||
class nsIWeakReference;
|
||||
|
||||
// Weak references
|
||||
class MOZ_STACK_CLASS nsQueryReferent final
|
||||
{
|
||||
public:
|
||||
nsQueryReferent(nsIWeakReference* aWeakPtr, nsresult* aError)
|
||||
: mWeakPtr(aWeakPtr)
|
||||
, mErrorPtr(aError)
|
||||
{
|
||||
}
|
||||
|
||||
nsresult NS_FASTCALL operator()(const nsIID& aIID, void**) const;
|
||||
|
||||
private:
|
||||
nsIWeakReference* MOZ_NON_OWNING_REF mWeakPtr;
|
||||
nsresult* mErrorPtr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Factors implementation for all template versions of nsCOMPtr.
|
||||
*
|
||||
@ -311,6 +330,8 @@ public:
|
||||
assign_from_gs_contractid_with_error(const nsGetServiceByContractIDWithError&,
|
||||
const nsIID&);
|
||||
void NS_FASTCALL
|
||||
assign_from_query_referent(const nsQueryReferent&, const nsIID&);
|
||||
void NS_FASTCALL
|
||||
assign_from_helper(const nsCOMPtr_helper&, const nsIID&);
|
||||
void** NS_FASTCALL
|
||||
begin_assignment();
|
||||
@ -366,6 +387,7 @@ private:
|
||||
void assign_from_gs_contractid(const nsGetServiceByContractID, const nsIID&);
|
||||
void assign_from_gs_contractid_with_error(
|
||||
const nsGetServiceByContractIDWithError&, const nsIID&);
|
||||
void assign_from_query_referent(const nsQueryReferent&, const nsIID&);
|
||||
void assign_from_helper(const nsCOMPtr_helper&, const nsIID&);
|
||||
void** begin_assignment();
|
||||
|
||||
@ -564,6 +586,15 @@ public:
|
||||
assign_from_gs_contractid_with_error(aGS, NS_GET_TEMPLATE_IID(T));
|
||||
}
|
||||
|
||||
// Construct from |do_QueryReferent(ptr)|
|
||||
MOZ_IMPLICIT nsCOMPtr(const nsQueryReferent& aQueryReferent)
|
||||
: NSCAP_CTOR_BASE(nullptr)
|
||||
{
|
||||
assert_validity();
|
||||
NSCAP_LOG_ASSIGNMENT(this, nullptr);
|
||||
assign_from_query_referent(aQueryReferent, NS_GET_TEMPLATE_IID(T));
|
||||
}
|
||||
|
||||
// And finally, anything else we might need to construct from can exploit the
|
||||
// nsCOMPtr_helper facility.
|
||||
MOZ_IMPLICIT nsCOMPtr(const nsCOMPtr_helper& aHelper)
|
||||
@ -667,6 +698,13 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign from |do_QueryReferent(ptr)|.
|
||||
nsCOMPtr<T>& operator=(const nsQueryReferent& aRhs)
|
||||
{
|
||||
assign_from_query_referent(aRhs, NS_GET_TEMPLATE_IID(T));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// And finally, anything else we might need to assign from can exploit the
|
||||
// nsCOMPtr_helper facility.
|
||||
nsCOMPtr<T>& operator=(const nsCOMPtr_helper& aRhs)
|
||||
@ -898,6 +936,14 @@ public:
|
||||
assign_from_gs_contractid_with_error(aGS, NS_GET_IID(nsISupports));
|
||||
}
|
||||
|
||||
// Construct from |do_QueryReferent(ptr)|
|
||||
MOZ_IMPLICIT nsCOMPtr(const nsQueryReferent& aQueryReferent)
|
||||
: nsCOMPtr_base(nullptr)
|
||||
{
|
||||
NSCAP_LOG_ASSIGNMENT(this, nullptr);
|
||||
assign_from_query_referent(aQueryReferent, NS_GET_TEMPLATE_IID(nsISupports));
|
||||
}
|
||||
|
||||
// And finally, anything else we might need to construct from can exploit
|
||||
// the |nsCOMPtr_helper| facility
|
||||
MOZ_IMPLICIT nsCOMPtr(const nsCOMPtr_helper& aHelper)
|
||||
@ -984,6 +1030,13 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign from |do_QueryReferent(ptr)|.
|
||||
nsCOMPtr<nsISupports>& operator=(const nsQueryReferent& aRhs)
|
||||
{
|
||||
assign_from_query_referent(aRhs, NS_GET_TEMPLATE_IID(nsISupports));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// And finally, anything else we might need to assign from can exploit the
|
||||
// nsCOMPtr_helper facility
|
||||
nsCOMPtr<nsISupports>& operator=(const nsCOMPtr_helper& aRhs)
|
||||
@ -1177,6 +1230,18 @@ nsCOMPtr<T>::assign_from_gs_contractid_with_error(
|
||||
assign_assuming_AddRef(static_cast<T*>(newRawPtr));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
nsCOMPtr<T>::assign_from_query_referent(
|
||||
const nsQueryReferent& aQueryReferent, const nsIID& aIID)
|
||||
{
|
||||
void* newRawPtr;
|
||||
if (NS_FAILED(aQueryReferent(aIID, &newRawPtr))) {
|
||||
newRawPtr = nullptr;
|
||||
}
|
||||
assign_assuming_AddRef(static_cast<T*>(newRawPtr));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
nsCOMPtr<T>::assign_from_helper(const nsCOMPtr_helper& helper, const nsIID& aIID)
|
||||
@ -1440,6 +1505,16 @@ CallQueryInterface(nsCOMPtr<SourceType>& aSourcePtr, DestinationType** aDestPtr)
|
||||
return CallQueryInterface(aSourcePtr.get(), aDestPtr);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
RefPtr<T>::RefPtr(const nsQueryReferent& aQueryReferent)
|
||||
{
|
||||
void* newRawPtr;
|
||||
if (NS_FAILED(aQueryReferent(NS_GET_TEMPLATE_IID(T), &newRawPtr))) {
|
||||
newRawPtr = nullptr;
|
||||
}
|
||||
mRawPtr = static_cast<T*>(newRawPtr);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
RefPtr<T>::RefPtr(const nsCOMPtr_helper& aHelper)
|
||||
{
|
||||
@ -1450,6 +1525,18 @@ RefPtr<T>::RefPtr(const nsCOMPtr_helper& aHelper)
|
||||
mRawPtr = static_cast<T*>(newRawPtr);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
RefPtr<T>&
|
||||
RefPtr<T>::operator=(const nsQueryReferent& aQueryReferent)
|
||||
{
|
||||
void* newRawPtr;
|
||||
if (NS_FAILED(aQueryReferent(NS_GET_TEMPLATE_IID(T), &newRawPtr))) {
|
||||
newRawPtr = nullptr;
|
||||
}
|
||||
assign_assuming_AddRef(static_cast<T*>(newRawPtr));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
RefPtr<T>&
|
||||
RefPtr<T>::operator=(const nsCOMPtr_helper& aHelper)
|
||||
|
@ -30,23 +30,6 @@ CallQueryReferent(T* aSource, DestinationType** aDestination)
|
||||
}
|
||||
|
||||
|
||||
class MOZ_STACK_CLASS nsQueryReferent final : public nsCOMPtr_helper
|
||||
{
|
||||
public:
|
||||
nsQueryReferent(nsIWeakReference* aWeakPtr, nsresult* aError)
|
||||
: mWeakPtr(aWeakPtr)
|
||||
, mErrorPtr(aError)
|
||||
{
|
||||
}
|
||||
|
||||
virtual nsresult NS_FASTCALL operator()(const nsIID& aIID, void**) const
|
||||
override;
|
||||
|
||||
private:
|
||||
nsIWeakReference* MOZ_NON_OWNING_REF mWeakPtr;
|
||||
nsresult* mErrorPtr;
|
||||
};
|
||||
|
||||
inline const nsQueryReferent
|
||||
do_QueryReferent(nsIWeakReference* aRawPtr, nsresult* aError = 0)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user