diff --git a/dom/indexedDB/IDBCursor.cpp b/dom/indexedDB/IDBCursor.cpp index 772f18ceca73..9cd926f04c9b 100644 --- a/dom/indexedDB/IDBCursor.cpp +++ b/dom/indexedDB/IDBCursor.cpp @@ -255,7 +255,7 @@ IDBCursor::IDBCursor() : mDirection(nsIIDBCursor::NEXT), mCachedValue(JSVAL_VOID), mHaveCachedValue(false), - mJSRuntime(nsnull), + mValueRooted(false), mContinueCalled(false), mDataIndex(0), mType(OBJECTSTORE) @@ -267,8 +267,8 @@ IDBCursor::~IDBCursor() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - if (mJSRuntime) { - js_RemoveRoot(mJSRuntime, &mCachedValue); + if (mValueRooted) { + NS_DROP_JS_OBJECTS(this, IDBCursor); } if (mListenerManager) { @@ -280,18 +280,38 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(IDBCursor) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBCursor, nsDOMEventTargetHelper) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mRequest, + nsPIDOMEventTarget) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTransaction, + nsPIDOMEventTarget) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mObjectStore, nsPIDOMEventTarget) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mIndex, nsPIDOMEventTarget) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mTransaction, - nsPIDOMEventTarget) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(IDBCursor) + if (tmp->mValueRooted) { + NS_DROP_JS_OBJECTS(tmp, IDBCursor); + tmp->mCachedValue = JSVAL_VOID; + tmp->mHaveCachedValue = false; + tmp->mValueRooted = false; + } +NS_IMPL_CYCLE_COLLECTION_ROOT_END + +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBCursor) + if (JSVAL_IS_GCTHING(tmp->mCachedValue)) { + void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedValue); + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing) + } +NS_IMPL_CYCLE_COLLECTION_TRACE_END + NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBCursor, nsDOMEventTargetHelper) // Don't unlink mObjectStore, mIndex, or mTransaction! + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRequest) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener) NS_IMPL_CYCLE_COLLECTION_UNLINK_END @@ -377,19 +397,15 @@ IDBCursor::GetValue(JSContext* aCx, if (!mHaveCachedValue) { JSAutoRequest ar(aCx); - if (!mJSRuntime) { - JSRuntime* rt = JS_GetRuntime(aCx); - JSBool ok = js_AddRootRT(rt, &mCachedValue, - "IDBCursor::mCachedValue"); - NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); - - mJSRuntime = rt; - } - nsCOMPtr json(new nsJSON()); rv = json->DecodeToJSVal(mData[mDataIndex].value, aCx, &mCachedValue); NS_ENSURE_SUCCESS(rv, rv); + if (!mValueRooted) { + NS_HOLD_JS_OBJECTS(this, IDBCursor); + mValueRooted = true; + } + mHaveCachedValue = true; } diff --git a/dom/indexedDB/IDBCursor.h b/dom/indexedDB/IDBCursor.h index 327a5a012e02..304abfcf038f 100644 --- a/dom/indexedDB/IDBCursor.h +++ b/dom/indexedDB/IDBCursor.h @@ -78,8 +78,8 @@ public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIIDBCURSOR - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBCursor, - nsDOMEventTargetHelper) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBCursor, + nsDOMEventTargetHelper) static already_AddRefed @@ -137,7 +137,7 @@ protected: nsCOMPtr mCachedKey; jsval mCachedValue; bool mHaveCachedValue; - JSRuntime* mJSRuntime; + bool mValueRooted; bool mContinueCalled; PRUint32 mDataIndex; diff --git a/dom/indexedDB/IDBEvents.cpp b/dom/indexedDB/IDBEvents.cpp index 769017c03d5e..1d3b94f05139 100644 --- a/dom/indexedDB/IDBEvents.cpp +++ b/dom/indexedDB/IDBEvents.cpp @@ -205,7 +205,17 @@ IDBEvent::CreateGenericEventRunnable(const nsAString& aType, NS_IMPL_ADDREF_INHERITED(IDBEvent, nsDOMEvent) NS_IMPL_RELEASE_INHERITED(IDBEvent, nsDOMEvent) -NS_INTERFACE_MAP_BEGIN(IDBEvent) +NS_IMPL_CYCLE_COLLECTION_CLASS(IDBEvent) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBEvent, nsDOMEvent) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSource) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBEvent, nsDOMEvent) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBEvent) NS_INTERFACE_MAP_ENTRY(nsIIDBEvent) NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent) @@ -331,7 +341,19 @@ IDBSuccessEvent::CreateRunnable(IDBRequest* aRequest, NS_IMPL_ADDREF_INHERITED(IDBSuccessEvent, IDBEvent) NS_IMPL_RELEASE_INHERITED(IDBSuccessEvent, IDBEvent) -NS_INTERFACE_MAP_BEGIN(IDBSuccessEvent) +NS_IMPL_CYCLE_COLLECTION_CLASS(IDBSuccessEvent) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBSuccessEvent, IDBEvent) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mResult) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTransaction) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBSuccessEvent, IDBEvent) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mResult) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTransaction) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBSuccessEvent) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIDBTransactionEvent, mTransaction) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(IDBTransactionEvent, mTransaction) @@ -372,6 +394,13 @@ IDBSuccessEvent::GetTransaction(nsIIDBTransaction** aTransaction) return NS_OK; } +GetSuccessEvent::~GetSuccessEvent() +{ + if (mValueRooted) { + NS_DROP_JS_OBJECTS(this, GetSuccessEvent); + } +} + nsresult GetSuccessEvent::Init(IDBRequest* aRequest, IDBTransaction* aTransaction) @@ -398,20 +427,14 @@ GetSuccessEvent::GetResult(JSContext* aCx, return NS_OK; } - if (!mJSRuntime) { + if (!mValueRooted) { + RootCachedValue(); + nsString jsonValue = mValue; mValue.Truncate(); JSAutoRequest ar(aCx); - JSRuntime* rt = JS_GetRuntime(aCx); - - JSBool ok = js_AddRootRT(rt, &mCachedValue, - "GetSuccessEvent::mCachedValue"); - NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); - - mJSRuntime = rt; - nsCOMPtr json(new nsJSON()); nsresult rv = json->DecodeToJSVal(jsonValue, aCx, &mCachedValue); if (NS_FAILED(rv)) { @@ -426,21 +449,56 @@ GetSuccessEvent::GetResult(JSContext* aCx, return NS_OK; } +void +GetSuccessEvent::RootCachedValue() +{ + mValueRooted = PR_TRUE; + NS_HOLD_JS_OBJECTS(this, GetSuccessEvent); +} + +NS_IMPL_ADDREF_INHERITED(GetSuccessEvent, IDBSuccessEvent) +NS_IMPL_RELEASE_INHERITED(GetSuccessEvent, IDBSuccessEvent) + +NS_IMPL_CYCLE_COLLECTION_CLASS(GetSuccessEvent) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(GetSuccessEvent, + IDBSuccessEvent) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(GetSuccessEvent) + if (tmp->mValueRooted) { + NS_DROP_JS_OBJECTS(tmp, GetSuccessEvent); + tmp->mCachedValue = JSVAL_VOID; + tmp->mValueRooted = PR_FALSE; + } +NS_IMPL_CYCLE_COLLECTION_ROOT_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(GetSuccessEvent, + IDBSuccessEvent) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mResult) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTransaction) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(GetSuccessEvent) + if (JSVAL_IS_GCTHING(tmp->mCachedValue)) { + void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedValue); + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing) + } +NS_IMPL_CYCLE_COLLECTION_TRACE_END + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(GetSuccessEvent) +NS_INTERFACE_MAP_END_INHERITING(IDBSuccessEvent) + NS_IMETHODIMP GetAllSuccessEvent::GetResult(JSContext* aCx, jsval* aResult) { - if (!mJSRuntime) { + if (!mValueRooted) { + RootCachedValue(); + JSAutoRequest ar(aCx); - JSRuntime* rt = JS_GetRuntime(aCx); - - JSBool ok = js_AddRootRT(rt, &mCachedValue, - "GetSuccessEvent::mCachedValue"); - NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); - - mJSRuntime = rt; - // Swap into a stack array so that we don't hang on to the strings if // something fails. nsTArray values; @@ -497,17 +555,11 @@ NS_IMETHODIMP GetAllKeySuccessEvent::GetResult(JSContext* aCx, jsval* aResult) { - if (!mJSRuntime) { + if (!mValueRooted) { + RootCachedValue(); + JSAutoRequest ar(aCx); - JSRuntime* rt = JS_GetRuntime(aCx); - - JSBool ok = js_AddRootRT(rt, &mCachedValue, - "GetSuccessEvent::mCachedValue"); - NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE); - - mJSRuntime = rt; - // Swap into a stack array so that we don't hang on to the strings if // something fails. nsTArray keys; diff --git a/dom/indexedDB/IDBEvents.h b/dom/indexedDB/IDBEvents.h index ad8b5c5f4169..9e90efc592ab 100644 --- a/dom/indexedDB/IDBEvents.h +++ b/dom/indexedDB/IDBEvents.h @@ -73,6 +73,8 @@ public: NS_DECL_NSIIDBEVENT NS_FORWARD_TO_NSDOMEVENT + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBEvent, nsDOMEvent) + static already_AddRefed CreateGenericEvent(const nsAString& aType); @@ -121,6 +123,8 @@ public: NS_FORWARD_NSIDOMEVENT(IDBEvent::) NS_FORWARD_NSIIDBEVENT(IDBEvent::) + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBSuccessEvent, IDBEvent) + static already_AddRefed Create(IDBRequest* aRequest, nsIVariant* aResult, @@ -144,15 +148,14 @@ public: GetSuccessEvent(const nsAString& aValue) : mValue(aValue), mCachedValue(JSVAL_VOID), - mJSRuntime(nsnull) + mValueRooted(PR_FALSE) { } - ~GetSuccessEvent() - { - if (mJSRuntime) { - js_RemoveRoot(mJSRuntime, &mCachedValue); - } - } + ~GetSuccessEvent(); + + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(GetSuccessEvent, + IDBSuccessEvent) NS_IMETHOD GetResult(JSContext* aCx, jsval* aResult); @@ -164,8 +167,11 @@ private: nsString mValue; protected: + void RootCachedValue(); + jsval mCachedValue; JSRuntime* mJSRuntime; + PRBool mValueRooted; }; class GetAllSuccessEvent : public GetSuccessEvent diff --git a/dom/indexedDB/IDBRequest.cpp b/dom/indexedDB/IDBRequest.cpp index 0c1f85b8c067..1d0f2ba82103 100644 --- a/dom/indexedDB/IDBRequest.cpp +++ b/dom/indexedDB/IDBRequest.cpp @@ -113,12 +113,14 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest, nsDOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnSuccessListener) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSource) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest, nsDOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnSuccessListener) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBRequest)