Bug 715761 - Replace xpconnect automarker macros with templates (r=bholley)

This commit is contained in:
Bill McCloskey 2012-05-07 10:01:44 -07:00
Родитель 7e5ea5b6ee
Коммит c972487a40
3 изменённых файлов: 113 добавлений и 142 удалений

Просмотреть файл

@ -977,19 +977,17 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
flat = cache->GetWrapper();
}
XPCCallContext &ccx = lccx.GetXPCCallContext();
if (!ccx.IsValid())
return false;
// We can't simply construct a slim wrapper. Go ahead and create an
// XPCWrappedNative for this object. At this point, |flat| could be
// non-null, meaning that either we already have a wrapped native from
// the cache (which might need to be QI'd to the new interface) or that
// we found a slim wrapper that we'll have to morph.
AutoMarkingNativeInterfacePtr iface;
AutoMarkingNativeInterfacePtr iface(ccx);
if (iid) {
XPCCallContext &ccx = lccx.GetXPCCallContext();
if (!ccx.IsValid())
return false;
iface.Init(ccx);
if (Interface)
iface = *Interface;
@ -1010,10 +1008,6 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
XPCWrappedNative* wrapper;
nsRefPtr<XPCWrappedNative> strongWrapper;
if (!flat) {
XPCCallContext &ccx = lccx.GetXPCCallContext();
if (!ccx.IsValid())
return false;
rv = XPCWrappedNative::GetNewOrUsed(ccx, aHelper, xpcscope, iface,
getter_AddRefs(strongWrapper));
@ -1030,18 +1024,13 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
// a valid XPCCallContext because we checked when calling Init on
// iface.
if (iface)
wrapper->FindTearOff(lccx.GetXPCCallContext(), iface, false,
&rv);
wrapper->FindTearOff(ccx, iface, false, &rv);
else
rv = NS_OK;
} else {
NS_ASSERTION(IS_SLIM_WRAPPER(flat),
"What kind of wrapper is this?");
XPCCallContext &ccx = lccx.GetXPCCallContext();
if (!ccx.IsValid())
return false;
SLIM_LOG(("***** morphing from XPCConvert::NativeInterface2JSObject"
"(%p)\n",
static_cast<nsISupports*>(xpc_GetJSPrivate(flat))));
@ -1072,10 +1061,6 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
return true;
}
XPCCallContext &ccx = lccx.GetXPCCallContext();
if (!ccx.IsValid())
return false;
JSObject *original = flat;
if (!JS_WrapObject(ccx, &flat))
return false;

Просмотреть файл

@ -299,8 +299,7 @@ XPCPerThreadData::XPCPerThreadData()
void
XPCPerThreadData::Cleanup()
{
while (mAutoRoots)
mAutoRoots->Unlink();
MOZ_ASSERT(!mAutoRoots);
NS_IF_RELEASE(mExceptionManager);
NS_IF_RELEASE(mException);
delete mJSContextStack;
@ -369,13 +368,13 @@ void XPCPerThreadData::TraceJS(JSTracer *trc)
#endif
if (mAutoRoots)
mAutoRoots->TraceJS(trc);
mAutoRoots->TraceJSAll(trc);
}
void XPCPerThreadData::MarkAutoRootsAfterJSFinalize()
{
if (mAutoRoots)
mAutoRoots->MarkAfterJSFinalize();
mAutoRoots->MarkAfterJSFinalizeAll();
}
// static

Просмотреть файл

@ -4138,140 +4138,127 @@ private:
class AutoMarkingPtr
{
public:
AutoMarkingPtr(XPCCallContext& ccx)
: mNext(nsnull), mTLS(ccx.GetThreadData()) {Link();}
AutoMarkingPtr()
: mNext(nsnull), mTLS(nsnull) {}
public:
AutoMarkingPtr(XPCCallContext& ccx) {
mRoot = ccx.GetThreadData()->GetAutoRootsAdr();
mNext = *mRoot;
*mRoot = this;
}
virtual ~AutoMarkingPtr() {Unlink();}
void Init(XPCCallContext& ccx)
{NS_ASSERTION(!mTLS, "Already init'ed!");
mTLS = ccx.GetThreadData();
Link();}
void Link()
{if (!mTLS) return;
AutoMarkingPtr** list = mTLS->GetAutoRootsAdr();
mNext = *list; *list = this;}
void Unlink()
{if (!mTLS) return;
AutoMarkingPtr** cur = mTLS->GetAutoRootsAdr();
while (*cur != this) {
NS_ASSERTION(*cur, "This object not in list!");
cur = &(*cur)->mNext;
}
*cur = mNext;
mTLS = nsnull;
virtual ~AutoMarkingPtr() {
if (mRoot) {
MOZ_ASSERT(*mRoot == this);
*mRoot = mNext;
}
}
AutoMarkingPtr* GetNext() {return mNext;}
void TraceJSAll(JSTracer* trc) {
for (AutoMarkingPtr *cur = this; cur; cur = cur->mNext)
cur->TraceJS(trc);
}
void MarkAfterJSFinalizeAll() {
for (AutoMarkingPtr *cur = this; cur; cur = cur->mNext)
cur->MarkAfterJSFinalize();
}
protected:
virtual void TraceJS(JSTracer* trc) = 0;
virtual void MarkAfterJSFinalize() = 0;
protected:
private:
AutoMarkingPtr** mRoot;
AutoMarkingPtr* mNext;
XPCPerThreadData* mTLS;
};
// More joy of macros...
template<class T>
class TypedAutoMarkingPtr : public AutoMarkingPtr
{
public:
TypedAutoMarkingPtr(XPCCallContext& ccx) : AutoMarkingPtr(ccx), mPtr(nsnull) {}
TypedAutoMarkingPtr(XPCCallContext& ccx, T* ptr) : AutoMarkingPtr(ccx), mPtr(ptr) {}
#define DEFINE_AUTO_MARKING_PTR_TYPE(class_, type_) \
class class_ : public AutoMarkingPtr \
{ \
public: \
class_ () \
: AutoMarkingPtr(), mPtr(nsnull) {} \
class_ (XPCCallContext& ccx, type_ * ptr = nsnull) \
: AutoMarkingPtr(ccx), mPtr(ptr) {} \
virtual ~ class_ () {} \
\
virtual void TraceJS(JSTracer* trc) \
{if (mPtr) { \
mPtr->TraceJS(trc); \
mPtr->AutoTrace(trc); \
} \
if (mNext) mNext->TraceJS(trc);} \
\
virtual void MarkAfterJSFinalize() \
{if (mPtr) mPtr->Mark(); \
if (mNext) mNext->MarkAfterJSFinalize();} \
\
type_ * get() const {return mPtr;} \
operator type_ *() const {return mPtr;} \
type_ * operator->() const {return mPtr;} \
\
class_ & operator =(type_ * p) \
{NS_ASSERTION(mTLS, "Hasn't been init'ed!"); \
mPtr = p; return *this;} \
\
protected: \
type_ * mPtr; \
T* get() const { return mPtr; }
operator T *() const { return mPtr; }
T* operator->() const { return mPtr; }
TypedAutoMarkingPtr<T>& operator =(T* ptr) { mPtr = ptr; return *this; }
protected:
virtual void TraceJS(JSTracer* trc)
{
if (mPtr) {
mPtr->TraceJS(trc);
mPtr->AutoTrace(trc);
}
}
virtual void MarkAfterJSFinalize()
{
if (mPtr)
mPtr->Mark();
}
private:
T* mPtr;
};
// Use the macro above to define our AutoMarking types...
typedef TypedAutoMarkingPtr<XPCNativeInterface> AutoMarkingNativeInterfacePtr;
typedef TypedAutoMarkingPtr<XPCNativeSet> AutoMarkingNativeSetPtr;
typedef TypedAutoMarkingPtr<XPCWrappedNative> AutoMarkingWrappedNativePtr;
typedef TypedAutoMarkingPtr<XPCWrappedNativeTearOff> AutoMarkingWrappedNativeTearOffPtr;
typedef TypedAutoMarkingPtr<XPCWrappedNativeProto> AutoMarkingWrappedNativeProtoPtr;
typedef TypedAutoMarkingPtr<XPCMarkableJSVal> AutoMarkingJSVal;
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingNativeInterfacePtr, XPCNativeInterface)
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingNativeSetPtr, XPCNativeSet)
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativePtr, XPCWrappedNative)
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeTearOffPtr, XPCWrappedNativeTearOff)
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeProtoPtr, XPCWrappedNativeProto)
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingJSVal, XPCMarkableJSVal)
template<class T>
class ArrayAutoMarkingPtr : public AutoMarkingPtr
{
public:
ArrayAutoMarkingPtr(XPCCallContext& ccx)
: AutoMarkingPtr(ccx), mPtr(nsnull), mCount(0) {}
ArrayAutoMarkingPtr(XPCCallContext& ccx, T** ptr, PRUint32 count, bool clear)
: AutoMarkingPtr(ccx), mPtr(ptr), mCount(count)
{
if (!mPtr) mCount = 0;
else if (clear) memset(mPtr, 0, mCount*sizeof(T*));
}
#define DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(class_, type_) \
class class_ : public AutoMarkingPtr \
{ \
public: \
class_ (XPCCallContext& ccx) \
: AutoMarkingPtr(ccx), mPtr(nsnull), mCount(0) {} \
class_ (XPCCallContext& ccx, type_** aPtr, PRUint32 aCount, \
bool aClear = false) \
: AutoMarkingPtr(ccx), mPtr(aPtr), mCount(aCount) \
{ \
if (!mPtr) mCount = 0; \
else if (aClear) memset(mPtr, 0, mCount*sizeof(type_*)); \
} \
virtual ~ class_ () {} \
\
virtual void TraceJS(JSTracer* trc) \
{ \
for (PRUint32 i = 0; i < mCount; ++i) { \
type_* cur = mPtr[i]; \
if (cur) { \
cur->TraceJS(trc); \
cur->AutoTrace(trc); \
} \
} \
if (mNext) mNext->TraceJS(trc); \
} \
\
virtual void MarkAfterJSFinalize() \
{ \
for (PRUint32 i = 0; i < mCount; ++i) { \
type_* cur = mPtr[i]; \
if (cur) \
cur->Mark(); \
} \
if (mNext) mNext->MarkAfterJSFinalize(); \
} \
\
type_ ** get() const {return mPtr;} \
operator type_ **() const {return mPtr;} \
type_ ** operator->() const {return mPtr;} \
\
class_ & operator =(const class_ & inst) \
{mPtr = inst.mPtr; mCount = inst.mCount; return *this;} \
\
protected: \
type_ ** mPtr; \
PRUint32 mCount; \
T** get() const { return mPtr; }
operator T **() const { return mPtr; }
T** operator->() const { return mPtr; }
ArrayAutoMarkingPtr<T>& operator =(const ArrayAutoMarkingPtr<T> &other)
{
mPtr = other.mPtr;
mCount = other.mCount;
return *this;
}
protected:
virtual void TraceJS(JSTracer* trc)
{
for (PRUint32 i = 0; i < mCount; i++) {
if (mPtr[i]) {
mPtr[i]->TraceJS(trc);
mPtr[i]->AutoTrace(trc);
}
}
}
virtual void MarkAfterJSFinalize()
{
for (PRUint32 i = 0; i < mCount; i++) {
if (mPtr[i])
mPtr[i]->Mark();
}
}
private:
T** mPtr;
PRUint32 mCount;
};
DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(AutoMarkingNativeInterfacePtrArrayPtr,
XPCNativeInterface)
typedef ArrayAutoMarkingPtr<XPCNativeInterface> AutoMarkingNativeInterfacePtrArrayPtr;
// Note: It looked like I would need one of these AutoMarkingPtr types for
// XPCNativeScriptableInfo in order to manage marking its