Bug 714633 - Release message manager related data structures more aggressively, r=jst

--HG--
extra : rebase_source : 5749ff9fc1ad21fd7a3d459198437e214b08fdfc
This commit is contained in:
Olli Pettay 2012-01-07 21:20:12 +02:00
Родитель 91e45d595a
Коммит b2279f77f1
6 изменённых файлов: 39 добавлений и 11 удалений

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

@ -90,7 +90,7 @@ public:
protected:
nsDOMEventTargetWrapperCache() : nsDOMEventTargetHelper(), nsWrapperCache() {}
virtual ~nsDOMEventTargetWrapperCache() {}
virtual ~nsDOMEventTargetWrapperCache();
};
#define NS_DECL_EVENT_HANDLER(_event) \

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

@ -93,3 +93,8 @@ nsDOMEventTargetWrapperCache::Init(JSContext* aCx)
mOwner = window->GetCurrentInnerWindow();
}
}
nsDOMEventTargetWrapperCache::~nsDOMEventTargetWrapperCache()
{
nsContentUtils::ReleaseWrapper(this, this);
}

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

@ -346,6 +346,28 @@ nsFrameMessageManager::Atob(const nsAString& aAsciiString,
return NS_OK;
}
class MMListenerRemover
{
public:
MMListenerRemover(nsFrameMessageManager* aMM)
: mMM(aMM), mWasHandlingMessage(aMM->mHandlingMessage)
{
mMM->mHandlingMessage = true;
}
~MMListenerRemover()
{
if (!mWasHandlingMessage) {
mMM->mHandlingMessage = false;
if (mMM->mDisconnected) {
mMM->mListeners.Clear();
}
}
}
bool mWasHandlingMessage;
nsRefPtr<nsFrameMessageManager> mMM;
};
nsresult
nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
const nsAString& aMessage,
@ -360,7 +382,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
}
if (mListeners.Length()) {
nsCOMPtr<nsIAtom> name = do_GetAtom(aMessage);
nsRefPtr<nsFrameMessageManager> kungfuDeathGrip(this);
MMListenerRemover lr(this);
for (PRUint32 i = 0; i < mListeners.Length(); ++i) {
if (mListeners[i].mMessage == name) {
@ -536,9 +558,13 @@ nsFrameMessageManager::Disconnect(bool aRemoveFromParent)
if (mParentManager && aRemoveFromParent) {
mParentManager->RemoveChildManager(this);
}
mDisconnected = true;
mParentManager = nsnull;
mCallbackData = nsnull;
mContext = nsnull;
if (!mHandlingMessage) {
mListeners.Clear();
}
}
nsresult

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

@ -92,7 +92,7 @@ public:
bool aGlobal = false,
bool aProcessManager = false)
: mChrome(aChrome), mGlobal(aGlobal), mIsProcessManager(aProcessManager),
mParentManager(aParentManager),
mHandlingMessage(false), mDisconnected(false), mParentManager(aParentManager),
mSyncCallback(aSyncCallback), mAsyncCallback(aAsyncCallback),
mLoadScriptCallback(aLoadScriptCallback), mCallbackData(aCallbackData),
mContext(aContext)
@ -181,11 +181,14 @@ public:
return sChildProcessManager;
}
protected:
friend class MMListenerRemover;
nsTArray<nsMessageListenerInfo> mListeners;
nsCOMArray<nsIContentFrameMessageManager> mChildManagers;
bool mChrome;
bool mGlobal;
bool mIsProcessManager;
bool mHandlingMessage;
bool mDisconnected;
nsFrameMessageManager* mParentManager;
nsSyncMessageCallback mSyncCallback;
nsAsyncMessageCallback mAsyncCallback;

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

@ -250,6 +250,8 @@ nsInProcessTabChildGlobal::DelayedDisconnect()
}
if (!mLoadingScript) {
nsContentUtils::ReleaseWrapper(static_cast<nsIDOMEventTarget*>(this),
this);
if (mCx) {
DestroyCx();
}

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

@ -450,14 +450,6 @@ nsXMLHttpRequest::~nsXMLHttpRequest()
NS_ABORT_IF_FALSE(!(mState & XML_HTTP_REQUEST_SYNCLOOPING), "we rather crash than hang");
mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
// This can happen if the XHR was only used by C++ (and so never created a JS
// wrapper) that also made an ArrayBuffer.
if (PreservingWrapper()) {
nsContentUtils::ReleaseWrapper(
static_cast<nsIDOMEventTarget*>(
static_cast<nsDOMEventTargetHelper*>(this)), this);
}
nsLayoutStatics::Release();
}