This commit is contained in:
Kyle Huey 2012-07-06 10:28:51 -07:00
Родитель afa3664115
Коммит 13d799f93d
11 изменённых файлов: 65 добавлений и 65 удалений

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

@ -1282,6 +1282,8 @@ public:
static nsresult DropJSObjects(void* aScriptObjectHolder); static nsresult DropJSObjects(void* aScriptObjectHolder);
#ifdef DEBUG #ifdef DEBUG
static bool AreJSObjectsHeld(void* aScriptObjectHolder);
static void CheckCCWrapperTraversal(nsISupports* aScriptObjectHolder, static void CheckCCWrapperTraversal(nsISupports* aScriptObjectHolder,
nsWrapperCache* aCache); nsWrapperCache* aCache);
#endif #endif

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

@ -4453,6 +4453,17 @@ nsContentUtils::DropJSObjects(void* aScriptObjectHolder)
return rv; return rv;
} }
#ifdef DEBUG
/* static */
bool
nsContentUtils::AreJSObjectsHeld(void* aScriptHolder)
{
bool isHeld = false;
sXPConnect->TestJSHolder(aScriptHolder, &isHeld);
return isHeld;
}
#endif
/* static */ /* static */
void void
nsContentUtils::NotifyInstalledMenuKeyboardListener(bool aInstalling) nsContentUtils::NotifyInstalledMenuKeyboardListener(bool aInstalling)

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

@ -18,6 +18,7 @@
#include "nsCharSeparatedTokenizer.h" #include "nsCharSeparatedTokenizer.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsDOMClassInfoID.h" #include "nsDOMClassInfoID.h"
#include "nsGlobalWindow.h"
#include "nsHashKeys.h" #include "nsHashKeys.h"
#include "nsPIDOMWindow.h" #include "nsPIDOMWindow.h"
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
@ -413,6 +414,8 @@ IDBFactory::OpenCommon(const nsAString& aName,
if (mWindow) { if (mWindow) {
window = mWindow; window = mWindow;
scriptOwner =
static_cast<nsGlobalWindow*>(window.get())->FastGetGlobalJSObject();
} }
else { else {
scriptOwner = mOwningObject; scriptOwner = mOwningObject;

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

@ -32,7 +32,6 @@ IDBRequest::IDBRequest()
mActorParent(nsnull), mActorParent(nsnull),
mErrorCode(NS_OK), mErrorCode(NS_OK),
mHaveResultOrErrorCode(false), mHaveResultOrErrorCode(false),
mRooted(false),
mLineNo(0) mLineNo(0)
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -41,8 +40,6 @@ IDBRequest::IDBRequest()
IDBRequest::~IDBRequest() IDBRequest::~IDBRequest()
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
UnrootResultVal();
} }
// static // static
@ -74,7 +71,6 @@ IDBRequest::Reset()
mResultVal = JSVAL_VOID; mResultVal = JSVAL_VOID;
mHaveResultOrErrorCode = false; mHaveResultOrErrorCode = false;
mError = nsnull; mError = nsnull;
UnrootResultVal();
} }
nsresult nsresult
@ -82,7 +78,6 @@ IDBRequest::NotifyHelperCompleted(HelperBase* aHelper)
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!"); NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!");
NS_ASSERTION(!PreservingWrapper(), "Already rooted?!");
NS_ASSERTION(JSVAL_IS_VOID(mResultVal), "Should be undefined!"); NS_ASSERTION(JSVAL_IS_VOID(mResultVal), "Should be undefined!");
// See if our window is still valid. If not then we're going to pretend that // See if our window is still valid. If not then we're going to pretend that
@ -116,7 +111,7 @@ IDBRequest::NotifyHelperCompleted(HelperBase* aHelper)
JSAutoRequest ar(cx); JSAutoRequest ar(cx);
JSAutoEnterCompartment ac; JSAutoEnterCompartment ac;
if (ac.enter(cx, global)) { if (ac.enter(cx, global)) {
RootResultVal(); AssertIsRooted();
rv = aHelper->GetSuccessResult(cx, &mResultVal); rv = aHelper->GetSuccessResult(cx, &mResultVal);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
@ -144,7 +139,6 @@ IDBRequest::NotifyHelperSentResultsToChildProcess(nsresult aRv)
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!"); NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!");
NS_ASSERTION(!PreservingWrapper(), "Already rooted?!");
NS_ASSERTION(JSVAL_IS_VOID(mResultVal), "Should be undefined!"); NS_ASSERTION(JSVAL_IS_VOID(mResultVal), "Should be undefined!");
// See if our window is still valid. If not then we're going to pretend that // See if our window is still valid. If not then we're going to pretend that
@ -171,7 +165,6 @@ IDBRequest::SetError(nsresult aRv)
mErrorCode = aRv; mErrorCode = aRv;
mResultVal = JSVAL_VOID; mResultVal = JSVAL_VOID;
UnrootResultVal();
} }
#ifdef DEBUG #ifdef DEBUG
@ -239,18 +232,6 @@ IDBRequest::FillScriptErrorEvent(nsScriptErrorEvent* aEvent) const
aEvent->fileName = mFilename.get(); aEvent->fileName = mFilename.get();
} }
void
IDBRequest::RootResultValInternal()
{
NS_HOLD_JS_OBJECTS(this, IDBRequest);
}
void
IDBRequest::UnrootResultValInternal()
{
NS_DROP_JS_OBJECTS(this, IDBRequest);
}
NS_IMETHODIMP NS_IMETHODIMP
IDBRequest::GetReadyState(nsAString& aReadyState) IDBRequest::GetReadyState(nsAString& aReadyState)
{ {
@ -327,7 +308,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest, IDBWrapperCache) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
tmp->mResultVal = JSVAL_VOID; tmp->mResultVal = JSVAL_VOID;
tmp->UnrootResultVal();
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(success) NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(success)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error) NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource)
@ -366,8 +346,6 @@ IDBRequest::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
IDBOpenDBRequest::~IDBOpenDBRequest() IDBOpenDBRequest::~IDBOpenDBRequest()
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
UnrootResultVal();
} }
// static // static
@ -400,18 +378,6 @@ IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction)
mTransaction = aTransaction; mTransaction = aTransaction;
} }
void
IDBOpenDBRequest::RootResultValInternal()
{
NS_HOLD_JS_OBJECTS(this, IDBOpenDBRequest);
}
void
IDBOpenDBRequest::UnrootResultValInternal()
{
NS_DROP_JS_OBJECTS(this, IDBOpenDBRequest);
}
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBOpenDBRequest) NS_IMPL_CYCLE_COLLECTION_CLASS(IDBOpenDBRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBOpenDBRequest, NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBOpenDBRequest,

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

@ -87,25 +87,6 @@ protected:
IDBRequest(); IDBRequest();
~IDBRequest(); ~IDBRequest();
virtual void RootResultValInternal();
virtual void UnrootResultValInternal();
void RootResultVal()
{
if (!mRooted) {
RootResultValInternal();
mRooted = true;
}
}
void UnrootResultVal()
{
if (mRooted) {
UnrootResultValInternal();
mRooted = false;
}
}
nsCOMPtr<nsISupports> mSource; nsCOMPtr<nsISupports> mSource;
nsRefPtr<IDBTransaction> mTransaction; nsRefPtr<IDBTransaction> mTransaction;
@ -120,7 +101,6 @@ protected:
nsresult mErrorCode; nsresult mErrorCode;
bool mHaveResultOrErrorCode; bool mHaveResultOrErrorCode;
bool mRooted;
nsString mFilename; nsString mFilename;
PRUint32 mLineNo; PRUint32 mLineNo;
@ -149,9 +129,6 @@ public:
protected: protected:
~IDBOpenDBRequest(); ~IDBOpenDBRequest();
virtual void RootResultValInternal();
virtual void UnrootResultValInternal();
// Only touched on the main thread. // Only touched on the main thread.
NS_DECL_EVENT_HANDLER(blocked) NS_DECL_EVENT_HANDLER(blocked)
NS_DECL_EVENT_HANDLER(upgradeneeded) NS_DECL_EVENT_HANDLER(upgradeneeded)

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

@ -48,13 +48,7 @@ IDBWrapperCache::~IDBWrapperCache()
bool bool
IDBWrapperCache::SetScriptOwner(JSObject* aScriptOwner) IDBWrapperCache::SetScriptOwner(JSObject* aScriptOwner)
{ {
if (!aScriptOwner) { NS_ASSERTION(aScriptOwner, "This should never be null!");
NS_ASSERTION(!mScriptOwner,
"Don't null out existing owner, we need to call "
"DropJSObjects!");
return true;
}
mScriptOwner = aScriptOwner; mScriptOwner = aScriptOwner;
@ -70,3 +64,12 @@ IDBWrapperCache::SetScriptOwner(JSObject* aScriptOwner)
return true; return true;
} }
#ifdef DEBUG
void
IDBWrapperCache::AssertIsRooted() const
{
NS_ASSERTION(nsContentUtils::AreJSObjectsHeld(const_cast<IDBWrapperCache*>(this)),
"Why aren't we rooted?!");
}
#endif

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

@ -46,6 +46,14 @@ public:
nsDOMEventTargetHelper::FromSupports(aSupports)); nsDOMEventTargetHelper::FromSupports(aSupports));
} }
#ifdef DEBUG
void AssertIsRooted() const;
#else
inline void AssertIsRooted() const
{
}
#endif
protected: protected:
IDBWrapperCache() IDBWrapperCache()
: mScriptOwner(nsnull) : mScriptOwner(nsnull)

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

@ -673,6 +673,13 @@ interface nsIXPConnect : nsISupports
*/ */
[noscript] void removeJSHolder(in voidPtr aHolder); [noscript] void removeJSHolder(in voidPtr aHolder);
/**
* Test to see if a JS holder is in our hashtable.
* Only available in debug builds.
* @param aHolder The object to test for.
*/
[noscript] bool testJSHolder(in voidPtr aHolder);
/** /**
* Note aJSContext as a child to the cycle collector. * Note aJSContext as a child to the cycle collector.
* @param aJSContext The JSContext to note. * @param aJSContext The JSContext to note.

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

@ -296,6 +296,17 @@ XPCJSRuntime::RemoveJSHolder(void* aHolder)
return NS_OK; return NS_OK;
} }
nsresult
XPCJSRuntime::TestJSHolder(void* aHolder, bool* aRetval)
{
if (!mJSHolders.ops)
return NS_ERROR_OUT_OF_MEMORY;
*aRetval = !!JS_DHashTableOperate(&mJSHolders, aHolder, JS_DHASH_LOOKUP);
return NS_OK;
}
// static // static
void XPCJSRuntime::TraceBlackJS(JSTracer* trc, void* data) void XPCJSRuntime::TraceBlackJS(JSTracer* trc, void* data)
{ {

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

@ -2260,6 +2260,17 @@ nsXPConnect::RemoveJSHolder(void* aHolder)
return mRuntime->RemoveJSHolder(aHolder); return mRuntime->RemoveJSHolder(aHolder);
} }
NS_IMETHODIMP
nsXPConnect::TestJSHolder(void* aHolder, bool* aRetval)
{
#ifdef DEBUG
return mRuntime->TestJSHolder(aHolder, aRetval);
#else
MOZ_ASSERT(false);
return NS_ERROR_FAILURE;
#endif
}
NS_IMETHODIMP NS_IMETHODIMP
nsXPConnect::SetReportAllJSExceptions(bool newval) nsXPConnect::SetReportAllJSExceptions(bool newval)
{ {

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

@ -763,6 +763,7 @@ public:
nsresult AddJSHolder(void* aHolder, nsScriptObjectTracer* aTracer); nsresult AddJSHolder(void* aHolder, nsScriptObjectTracer* aTracer);
nsresult RemoveJSHolder(void* aHolder); nsresult RemoveJSHolder(void* aHolder);
nsresult TestJSHolder(void* aHolder, bool* aRetval);
static void SuspectWrappedNative(XPCWrappedNative *wrapper, static void SuspectWrappedNative(XPCWrappedNative *wrapper,
nsCycleCollectionTraversalCallback &cb); nsCycleCollectionTraversalCallback &cb);