Bug 770840 - Add Runtime aborts when using XPCWrappedJS off-main-thread. v2
☠☠ backed out by 2673016e7df4 ☠ ☠
authorBobby Holley <bobbyholley@gmail.com>
Fri, 12 Apr 2013 15:35:00 -0400
changeset 138200 6be352955252d672cd4cadb6afd53eac616a8441
parent 138199 1bc459138617b42345ff7d27e01aa05776582993
child 138201 31ff9550fba69b0e222cc8d6112b1676ab0c7bb0
push id3752
push userlsblakk@mozilla.com
push dateMon, 13 May 2013 17:21:10 +0000
treeherdermozilla-aurora@1580544aef0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs770840
milestone23.0a1
Bug 770840 - Add Runtime aborts when using XPCWrappedJS off-main-thread. v2
js/xpconnect/src/XPCWrappedJS.cpp
--- a/js/xpconnect/src/XPCWrappedJS.cpp
+++ b/js/xpconnect/src/XPCWrappedJS.cpp
@@ -6,16 +6,17 @@
 
 /* Class that wraps JS objects to appear as XPCOM objects. */
 
 #include "xpcprivate.h"
 #include "nsAtomicRefcnt.h"
 #include "nsProxyRelease.h"
 #include "nsThreadUtils.h"
 #include "nsTextFormatter.h"
+#include "nsCycleCollectorUtils.h"
 
 // NOTE: much of the fancy footwork is done in xpcstubs.cpp
 
 NS_IMETHODIMP
 NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::TraverseImpl
    (NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS) *that, void *p,
     nsCycleCollectionTraversalCallback &cb)
 {
@@ -145,30 +146,34 @@ nsXPCWrappedJS::QueryInterface(REFNSIID 
 // collection. Code in XPCJSRuntime watches for JS gc to happen and will do
 // the final release on wrappers whose JSObjects get finalized. Note that
 // even after tranistioning to this refcount-of-one state callers might do
 // an addref and cause us to re-root the JSObject and continue on more normally.
 
 nsrefcnt
 nsXPCWrappedJS::AddRef(void)
 {
+    if (!MOZ_LIKELY(NS_IsMainThread() || NS_IsCycleCollectorThread()))
+        MOZ_CRASH();
     nsrefcnt cnt = NS_AtomicIncrementRefcnt(mRefCnt);
     NS_LOG_ADDREF(this, cnt, "nsXPCWrappedJS", sizeof(*this));
 
     if (2 == cnt && IsValid()) {
         XPCJSRuntime* rt = mClass->GetRuntime();
         rt->AddWrappedJSRoot(this);
     }
 
     return cnt;
 }
 
 nsrefcnt
 nsXPCWrappedJS::Release(void)
 {
+    if (!MOZ_LIKELY(NS_IsMainThread() || NS_IsCycleCollectorThread()))
+        MOZ_CRASH();
     NS_PRECONDITION(0 != mRefCnt, "dup release");
 
     if (mMainThreadOnly && !NS_IsMainThread()) {
         // We'd like to abort here, but this can happen if someone uses a proxy
         // for the nsXPCWrappedJS.
         nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
         // If we can't get the main thread anymore we just leak, but this really
         // shouldn't happen.
@@ -272,16 +277,20 @@ CheckMainThreadOnly(nsXPCWrappedJS *aWra
 // static
 nsresult
 nsXPCWrappedJS::GetNewOrUsed(JSContext* cx,
                              JSObject* aJSObj,
                              REFNSIID aIID,
                              nsISupports* aOuter,
                              nsXPCWrappedJS** wrapperResult)
 {
+    // Do a release-mode assert against accessing nsXPCWrappedJS off-main-thread.
+    if (!MOZ_LIKELY(NS_IsMainThread() || NS_IsCycleCollectorThread()))
+        MOZ_CRASH();
+
     JS::RootedObject jsObj(cx, aJSObj);
     JSObject2WrappedJSMap* map;
     nsXPCWrappedJS* root = nullptr;
     nsXPCWrappedJS* wrapper = nullptr;
     nsXPCWrappedJSClass* clazz = nullptr;
     XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
     JSBool release_root = false;
 
@@ -554,16 +563,20 @@ nsXPCWrappedJS::GetInterfaceInfo(nsIInte
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPCWrappedJS::CallMethod(uint16_t methodIndex,
                            const XPTMethodDescriptor* info,
                            nsXPTCMiniVariant* params)
 {
+    // Do a release-mode assert against accessing nsXPCWrappedJS off-main-thread.
+    if (!MOZ_LIKELY(NS_IsMainThread() || NS_IsCycleCollectorThread()))
+        MOZ_CRASH();
+
     if (!IsValid())
         return NS_ERROR_UNEXPECTED;
     if (NS_IsMainThread() != mMainThread) {
         NS_NAMED_LITERAL_STRING(kFmt, "Attempt to use JS function on a different thread calling %s.%s. JS objects may not be shared across threads.");
         PRUnichar* msg =
             nsTextFormatter::smprintf(kFmt.get(),
                                       GetClass()->GetInterfaceName(),
                                       info->name);