diff --git a/js/xpconnect/src/XPCInlines.h b/js/xpconnect/src/XPCInlines.h
index 91fd2f13af3fb5b5ea8e0bb253d02338c6705c63..27a4d53d1c74c5d8a77c7f3e5a52b9049cdc9bf9 100644
--- a/js/xpconnect/src/XPCInlines.h
+++ b/js/xpconnect/src/XPCInlines.h
@@ -582,11 +582,19 @@ inline void XPCNativeSet::ASSERT_NotMarked()
 /***************************************************************************/
 
 inline
-JSObject* XPCWrappedNativeTearOff::GetJSObject() const
+JSObject* XPCWrappedNativeTearOff::GetJSObjectPreserveColor() const
 {
     return mJSObject;
 }
 
+inline
+JSObject* XPCWrappedNativeTearOff::GetJSObject()
+{
+    JSObject *obj = GetJSObjectPreserveColor();
+    xpc_UnmarkGrayObject(obj);
+    return obj;
+}
+
 inline
 void XPCWrappedNativeTearOff::SetJSObject(JSObject*  JSObj)
 {
@@ -596,7 +604,7 @@ void XPCWrappedNativeTearOff::SetJSObject(JSObject*  JSObj)
 inline
 XPCWrappedNativeTearOff::~XPCWrappedNativeTearOff()
 {
-    NS_ASSERTION(!(GetInterface()||GetNative()||GetJSObject()), "tearoff not empty in dtor");
+    NS_ASSERTION(!(GetInterface()||GetNative()||GetJSObjectPreserveColor()), "tearoff not empty in dtor");
 }
 
 /***************************************************************************/
@@ -621,7 +629,7 @@ XPCWrappedNative::SweepTearOffs()
 
             // If this tearoff does not have a live dedicated JSObject,
             // then let's recycle it.
-            if (!to->GetJSObject()) {
+            if (!to->GetJSObjectPreserveColor()) {
                 nsISupports* obj = to->GetNative();
                 if (obj) {
                     obj->Release();
diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp
index 943c465b7270ad87274d6fdb866b35006d9e3214..93939fab1d895a4c2a89a98f4b8007f017862ea5 100644
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -171,7 +171,7 @@ XPCWrappedNative::NoteTearoffs(nsCycleCollectionTraversalCallback& cb)
     for (chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk) {
         XPCWrappedNativeTearOff* to = chunk->mTearOffs;
         for (int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK-1; i >= 0; i--, to++) {
-            JSObject* jso = to->GetJSObject();
+            JSObject* jso = to->GetJSObjectPreserveColor();
             if (!jso) {
                 NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "tearoff's mNative");
                 cb.NoteXPCOMChild(to->GetNative());
@@ -1259,7 +1259,7 @@ XPCWrappedNative::FlatJSObjectFinalized()
     for (chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk) {
         XPCWrappedNativeTearOff* to = chunk->mTearOffs;
         for (int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK-1; i >= 0; i--, to++) {
-            JSObject* jso = to->GetJSObject();
+            JSObject* jso = to->GetJSObjectPreserveColor();
             if (jso) {
                 NS_ASSERTION(JS_IsAboutToBeFinalized(jso), "bad!");
                 JS_SetPrivate(jso, nsnull);
@@ -1363,8 +1363,8 @@ XPCWrappedNative::SystemIsBeingShutDown()
     for (chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk) {
         XPCWrappedNativeTearOff* to = chunk->mTearOffs;
         for (int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK-1; i >= 0; i--, to++) {
-            if (to->GetJSObject()) {
-                JS_SetPrivate(to->GetJSObject(), nsnull);
+            if (JSObject *jso = to->GetJSObjectPreserveColor()) {
+                JS_SetPrivate(jso, nsnull);
                 to->SetJSObject(nsnull);
             }
             // We leak the tearoff mNative
@@ -1777,7 +1777,7 @@ XPCWrappedNative::FindTearOff(XPCCallContext& ccx,
              to < end;
              to++) {
             if (to->GetInterface() == aInterface) {
-                if (needJSObject && !to->GetJSObject()) {
+                if (needJSObject && !to->GetJSObjectPreserveColor()) {
                     AutoMarkingWrappedNativeTearOffPtr tearoff(ccx, to);
                     JSBool ok = InitTearOffJSObject(ccx, to);
                     // During shutdown, we don't sweep tearoffs.  So make sure
diff --git a/js/xpconnect/src/XPCWrappedNativeScope.cpp b/js/xpconnect/src/XPCWrappedNativeScope.cpp
index 8d78c9e336b563f6571ef248d4710c9e23ca5ee6..7dded7616a36db0b61200d9b884ed64e89b2adb5 100644
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -327,6 +327,8 @@ XPCWrappedNativeScope::GetPrototypeNoHelper(XPCCallContext& ccx)
 
         NS_ASSERTION(mPrototypeNoHelper,
                      "Failed to create prototype for wrappers w/o a helper");
+    } else {
+        xpc_UnmarkGrayObject(mPrototypeNoHelper);
     }
 
     return mPrototypeNoHelper;
diff --git a/js/xpconnect/src/dombindings.cpp b/js/xpconnect/src/dombindings.cpp
index 2ed5f3b75dda683b9ba6f0b2bb66d054d6914265..88aa3229f56a081bb7f653f0013f2ca19cd23792 100644
--- a/js/xpconnect/src/dombindings.cpp
+++ b/js/xpconnect/src/dombindings.cpp
@@ -491,8 +491,10 @@ ListBase<LC>::getPrototype(JSContext *cx, XPCWrappedNativeScope *scope)
 
     JSObject *interfacePrototype;
     if (cache.IsInitialized()) {
-        if (cache.Get(sInterfaceClass.name, &interfacePrototype))
+        if (cache.Get(sInterfaceClass.name, &interfacePrototype)) {
+            xpc_UnmarkGrayObject(interfacePrototype);
             return interfacePrototype;
+        }
     } else if (!cache.Init()) {
         return NULL;
     }
diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h
index 532b0320886ab814de278322a81fd0c9fb06fa21..404704255d3973b358b5358e348af9c4c71e816a 100644
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -2382,7 +2382,8 @@ public:
 
     XPCNativeInterface* GetInterface() const {return mInterface;}
     nsISupports*        GetNative()    const {return mNative;}
-    JSObject*           GetJSObject()  const;
+    JSObject*           GetJSObject();
+    JSObject*           GetJSObjectPreserveColor() const;
     void SetInterface(XPCNativeInterface*  Interface) {mInterface = Interface;}
     void SetNative(nsISupports*  Native)              {mNative = Native;}
     void SetJSObject(JSObject*  JSObj);
diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp
index d70333446bd0090dbb87825dd29035715bb0c32e..ea3885707a53ebe70f18d2ac0afcff78e66b4ac4 100644
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -103,8 +103,10 @@ WrapperFactory::WaiveXray(JSContext *cx, JSObject *obj)
         CompartmentPrivate *priv =
             (CompartmentPrivate *)JS_GetCompartmentPrivate(cx, js::GetObjectCompartment(obj));
         JSObject *wobj = nsnull;
-        if (priv && priv->waiverWrapperMap)
+        if (priv && priv->waiverWrapperMap) {
             wobj = priv->waiverWrapperMap->Find(obj);
+            xpc_UnmarkGrayObject(wobj);
+        }
 
         // No wrapper yet, make one.
         if (!wobj) {