mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-14 20:22:00 +00:00
Fix TOO_MUCH_GC issue with XPCNativeInterfaces. Bug 307313 r=dbradley, sr=brendan
This commit is contained in:
parent
b8cf83ad82
commit
8a8841aa28
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user