From 053f3e648d3a02b82dc96503a8a65c11d69d1b9d Mon Sep 17 00:00:00 2001 From: Sean Feng Date: Tue, 17 Mar 2020 14:53:00 +0000 Subject: [PATCH] Bug 1377999 - Make nsIContent to declare a final DeleteCycleCollectable r=smaug Differential Revision: https://phabricator.services.mozilla.com/D63263 --HG-- extra : moz-landing-system : lando --- dom/base/FragmentOrElement.cpp | 7 +++++-- dom/base/nsIContent.h | 5 ++++- xpcom/base/nsISupportsImpl.h | 25 +++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp index 6fd282796ccd..e5ce70618f36 100644 --- a/dom/base/FragmentOrElement.cpp +++ b/dom/base/FragmentOrElement.cpp @@ -144,8 +144,11 @@ NS_INTERFACE_MAP_BEGIN(nsIContent) NS_INTERFACE_MAP_END NS_IMPL_MAIN_THREAD_ONLY_CYCLE_COLLECTING_ADDREF(nsIContent) -NS_IMPL_MAIN_THREAD_ONLY_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE( - nsIContent, LastRelease()) + +NS_IMPL_DOMARENA_DESTROY(nsIContent) + +NS_IMPL_MAIN_THREAD_ONLY_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE_AND_DESTROY( + nsIContent, LastRelease(), Destroy()) nsIContent* nsIContent::FindFirstNonChromeOnlyAccessContent() const { // This handles also nested native anonymous content. diff --git a/dom/base/nsIContent.h b/dom/base/nsIContent.h index d557b02085fc..16c2ead2d5df 100644 --- a/dom/base/nsIContent.h +++ b/dom/base/nsIContent.h @@ -75,9 +75,12 @@ class nsIContent : public nsINode { NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENT_IID) - NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINAL_DELETECYCLECOLLECTABLE + NS_DECL_CYCLE_COLLECTION_CLASS(nsIContent) + NS_DECL_DOMARENA_DESTROY + NS_IMPL_FROMNODE_HELPER(nsIContent, IsContent()) /** diff --git a/xpcom/base/nsISupportsImpl.h b/xpcom/base/nsISupportsImpl.h index 1264066200ad..6b32fdf1a61e 100644 --- a/xpcom/base/nsISupportsImpl.h +++ b/xpcom/base/nsISupportsImpl.h @@ -936,6 +936,31 @@ class ThreadSafeAutoRefCnt { } \ NS_IMETHODIMP_(void) _class::DeleteCycleCollectable(void) { delete this; } +// _LAST_RELEASE can be useful when certain resources should be released +// as soon as we know the object will be deleted. +#define NS_IMPL_MAIN_THREAD_ONLY_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE_AND_DESTROY( \ + _class, _last, _destroy) \ + NS_IMETHODIMP_(MozExternalRefCountType) _class::Release(void) { \ + MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release"); \ + NS_ASSERT_OWNINGTHREAD(_class); \ + bool shouldDelete = false; \ + nsISupports* base = NS_CYCLE_COLLECTION_CLASSNAME(_class)::Upcast(this); \ + nsrefcnt count = mRefCnt.decr( \ + base, &shouldDelete); \ + NS_LOG_RELEASE(this, count, #_class); \ + if (count == 0) { \ + mRefCnt.incr(base); \ + _last; \ + mRefCnt.decr(base); \ + if (shouldDelete) { \ + mRefCnt.stabilizeForDeletion(); \ + DeleteCycleCollectable(); \ + } \ + } \ + return count; \ + } \ + NS_IMETHODIMP_(void) _class::DeleteCycleCollectable(void) { _destroy; } + /////////////////////////////////////////////////////////////////////////////// /**