Fix TOO_MUCH_GC issue with XPCNativeInterfaces. Bug 307313 r=dbradley, sr=brendan

This commit is contained in:
bzbarsky%mit.edu 2005-09-16 15:41:08 +00:00
parent b8cf83ad82
commit 8a8841aa28
3 changed files with 75 additions and 11 deletions

View File

@ -498,13 +498,19 @@ nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext,
if(aFlags & nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT)
JS_FlagSystemObject(aJSContext, tempGlobal);
if(NS_FAILED(InitClasses(aJSContext, tempGlobal)))
return UnexpectedFailure(NS_ERROR_FAILURE);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
if(NS_FAILED(WrapNative(aJSContext, tempGlobal, aCOMObj, aIID,
getter_AddRefs(holder))) || !holder)
return UnexpectedFailure(NS_ERROR_FAILURE);
{
// Scope for our auto-marker; it just needs to keep tempGlobal alive
// long enough for InitClasses and WrapNative to do their work
AUTO_MARK_JSVAL(ccx, OBJECT_TO_JSVAL(tempGlobal));
if(NS_FAILED(InitClasses(aJSContext, tempGlobal)))
return UnexpectedFailure(NS_ERROR_FAILURE);
if(NS_FAILED(WrapNative(aJSContext, tempGlobal, aCOMObj, aIID,
getter_AddRefs(holder))) || !holder)
return UnexpectedFailure(NS_ERROR_FAILURE);
}
JSObject* globalJSObj;
if(NS_FAILED(holder->GetJSObject(&globalJSObj)) || !globalJSObj)

View File

@ -3290,6 +3290,61 @@ DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeTearOffPtr, XPCWrappedNativ
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeProtoPtr, XPCWrappedNativeProto)
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingJSVal, XPCMarkableJSVal)
#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, \
PRBool aClear = PR_FALSE) \
: AutoMarkingPtr(ccx), mPtr(aPtr), mCount(aCount) \
{ \
if(!mPtr) mCount = 0; \
else if(aClear) memset(mPtr, 0, mCount*sizeof(type_*)); \
} \
virtual ~ class_ () {} \
\
virtual void MarkBeforeJSFinalize(JSContext* cx) \
{ \
for(PRUint32 i = 0; i < mCount; ++i) \
{ \
type_* cur = mPtr[i]; \
if(cur) \
{ \
cur->MarkBeforeJSFinalize(cx); \
cur->AutoMark(cx); \
} \
} \
if(mNext) mNext->MarkBeforeJSFinalize(cx); \
} \
\
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; \
};
DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(AutoMarkingNativeInterfacePtrArrayPtr,
XPCNativeInterface)
// Note: It looked like I would need one of these AutoMarkingPtr types for
// XPCNativeScriptableInfo in order to manage marking its
// XPCNativeScriptableShared member during construction. But AFAICT we build

View File

@ -593,7 +593,7 @@ XPCNativeSet::GetNewOrUsed(XPCCallContext& ccx, nsIClassInfo* classInfo)
return set;
nsIID** iidArray = nsnull;
XPCNativeInterface** interfaceArray = nsnull;
AutoMarkingNativeInterfacePtrArrayPtr interfaceArray(ccx);
PRUint32 iidCount = 0;
if(NS_FAILED(classInfo->GetInterfaces(&iidCount, &iidArray)))
@ -613,10 +613,13 @@ XPCNativeSet::GetNewOrUsed(XPCCallContext& ccx, nsIClassInfo* classInfo)
if(iidCount)
{
interfaceArray = new XPCNativeInterface*[iidCount];
if(!interfaceArray)
AutoMarkingNativeInterfacePtrArrayPtr
arr(ccx, new XPCNativeInterface*[iidCount], iidCount, PR_TRUE);
if (!arr)
goto out;
interfaceArray = arr;
XPCNativeInterface** currentInterface = interfaceArray;
nsIID** currentIID = iidArray;
PRUint16 interfaceCount = 0;
@ -629,8 +632,8 @@ XPCNativeSet::GetNewOrUsed(XPCCallContext& ccx, nsIClassInfo* classInfo)
continue;
}
AutoMarkingNativeInterfacePtr iface(ccx);
iface = XPCNativeInterface::GetNewOrUsed(ccx, iid);
XPCNativeInterface* iface =
XPCNativeInterface::GetNewOrUsed(ccx, iid);
if(!iface)
{