xpconnect-allocations
author Benjamin Smedberg <benjamin@smedbergs.us>
Sat, 26 Jul 2008 22:49:39 -0400
changeset 167 a4da40849f5436e629c5732f4368c6c48189637f
parent 124 0f6daec64ecb954b82b5a550327242837700329f
permissions -rw-r--r--
State as of now

* * *

diff --git a/js/src/xpconnect/src/XPCCrossOriginWrapper.cpp b/js/src/xpconnect/src/XPCCrossOriginWrapper.cpp
--- a/js/src/xpconnect/src/XPCCrossOriginWrapper.cpp
+++ b/js/src/xpconnect/src/XPCCrossOriginWrapper.cpp
@@ -902,6 +902,10 @@ JS_STATIC_DLL_CALLBACK(void)
 JS_STATIC_DLL_CALLBACK(void)
 XPC_XOW_Finalize(JSContext *cx, JSObject *obj)
 {
+  // TODO: I know that this is a JSAPI finalizer and not an MMgc finalizer, but
+  // it seems that it accesses all kinds of things that may have already
+  // been finalized. TODO bsmedberg
+
   JSObject *wrappedObj = GetWrappedObject(cx, obj);
   if (!wrappedObj) {
     return;
diff --git a/js/src/xpconnect/src/nsXPConnect.cpp b/js/src/xpconnect/src/nsXPConnect.cpp
--- a/js/src/xpconnect/src/nsXPConnect.cpp
+++ b/js/src/xpconnect/src/nsXPConnect.cpp
@@ -181,7 +181,6 @@ nsXPConnect::GetXPConnect()
         {
             // Initial extra ref to keep the singleton alive
             // balanced by explicit call to ReleaseXPConnectSingleton()
-            NS_ADDREF(gSelf);
             if (NS_FAILED(NS_SetGlobalThreadObserver(gSelf))) {
                 NS_RELEASE(gSelf);
                 // Fall through to returning null
@@ -196,7 +195,6 @@ nsXPConnect::GetSingleton()
 nsXPConnect::GetSingleton()
 {
     nsXPConnect* xpc = nsXPConnect::GetXPConnect();
-    NS_IF_ADDREF(xpc);
     return xpc;
 }
 
@@ -257,7 +255,6 @@ nsXPConnect::GetInterfaceInfoManager(nsI
         return NS_ERROR_FAILURE;
 
     *iim = xpc->mInterfaceInfoManager;
-    NS_IF_ADDREF(*iim);
     return NS_OK;
 }
 
@@ -272,7 +269,6 @@ nsXPConnect::GetContextStack(nsIThreadJS
         return NS_ERROR_FAILURE;
 
     *stack = temp = xpc->mContextStack;
-    NS_IF_ADDREF(temp);
     return NS_OK;
 }
 
@@ -577,7 +573,7 @@ nsXPConnect::InitClassesWithNewWrappedGl
     if (!XPC_SJOW_AttachNewConstructorObject(ccx, globalJSObj))
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
-    NS_ADDREF(*_retval = holder);
+    *_retval = holder;
 
     return NS_OK;
 }
@@ -685,7 +681,6 @@ nsXPConnect::GetWrappedNativeOfJSObject(
         XPCWrappedNative::GetWrappedNativeOfJSObject(aJSContext, aJSObj);
     if(wrapper)
     {
-        NS_ADDREF(wrapper);
         *_retval = wrapper;
         return NS_OK;
     }
@@ -718,7 +713,7 @@ nsXPConnect::GetWrappedNativeOfNativeObj
     if(!scope)
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
-    AutoMarkingNativeInterfacePtr iface(ccx);
+    XPCNativeInterface* iface;
     iface = XPCNativeInterface::GetNewOrUsed(ccx, &aIID);
     if(!iface)
         return NS_ERROR_FAILURE;
@@ -890,7 +885,6 @@ nsXPConnect::SetSecurityManagerForJSCont
 
     XPCContext* xpcc = ccx.GetXPCContext();
 
-    NS_IF_ADDREF(aManager);
     nsIXPCSecurityManager* oldManager = xpcc->GetSecurityManager();
     NS_IF_RELEASE(oldManager);
 
@@ -916,7 +910,6 @@ nsXPConnect::GetSecurityManagerForJSCont
     XPCContext* xpcc = ccx.GetXPCContext();
 
     nsIXPCSecurityManager* manager = xpcc->GetSecurityManager();
-    NS_IF_ADDREF(manager);
     *aManager = manager;
     *flags = xpcc->GetSecurityManagerFlags();
     return NS_OK;
@@ -927,7 +920,6 @@ nsXPConnect::SetDefaultSecurityManager(n
 nsXPConnect::SetDefaultSecurityManager(nsIXPCSecurityManager *aManager,
                                        PRUint16 flags)
 {
-    NS_IF_ADDREF(aManager);
     NS_IF_RELEASE(mDefaultSecurityManager);
     mDefaultSecurityManager = aManager;
     mDefaultSecurityManagerFlags = flags;
@@ -950,7 +942,6 @@ nsXPConnect::GetDefaultSecurityManager(n
     NS_ASSERTION(aManager, "bad param");
     NS_ASSERTION(flags, "bad param");
 
-    NS_IF_ADDREF(mDefaultSecurityManager);
     *aManager = mDefaultSecurityManager;
     *flags = mDefaultSecurityManagerFlags;
     return NS_OK;
@@ -1001,7 +992,7 @@ nsXPConnect::GetCurrentJSStack(nsIStackF
             {
                 stack = caller;
             }
-            NS_IF_ADDREF(*aCurrentJSStack = stack);
+            *aCurrentJSStack = stack;
         }
     }
     return NS_OK;
@@ -1079,7 +1070,6 @@ nsXPConnect::SetFunctionThisTranslator(c
         if(_retval)
         {
             old = map->Find(aIID);
-            NS_IF_ADDREF(old);
             *_retval = old;
         }
         map->Add(aIID, aTranslator);
@@ -1102,7 +1092,6 @@ nsXPConnect::GetFunctionThisTranslator(c
     {
         XPCAutoLock lock(rt->GetMapLock()); // scoped lock
         old = map->Find(aIID);
-        NS_IF_ADDREF(old);
         *_retval = old;
     }
     return NS_OK;
@@ -1245,7 +1234,6 @@ nsXPConnect::CreateSandbox(JSContext *cx
         *_retval = XPCJSObjectHolder::newHolder(ccx, JSVAL_TO_OBJECT(rval));
         NS_ENSURE_TRUE(*_retval, NS_ERROR_OUT_OF_MEMORY);
 
-        NS_ADDREF(*_retval);
     }
 
     return rv;
@@ -1309,7 +1297,7 @@ nsXPConnect::GetWrappedNativePrototype(J
     XPCNativeScriptableCreateInfo sciProto;
     XPCWrappedNative::GatherProtoScriptableCreateInfo(aClassInfo, &sciProto);
 
-    AutoMarkingWrappedNativeProtoPtr proto(ccx);
+    XPCWrappedNativeProto* proto;
     proto = XPCWrappedNativeProto::GetNewOrUsed(ccx, scope, aClassInfo, 
                                                 &sciProto, JS_FALSE,
                                                 OBJ_IS_NOT_GLOBAL);
@@ -1322,7 +1310,6 @@ nsXPConnect::GetWrappedNativePrototype(J
     if(!holder)
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
-    NS_ADDREF(holder);
     return NS_OK;
 }
 
diff --git a/js/src/xpconnect/src/xpccomponents.cpp b/js/src/xpconnect/src/xpccomponents.cpp
--- a/js/src/xpconnect/src/xpccomponents.cpp
+++ b/js/src/xpconnect/src/xpccomponents.cpp
@@ -217,7 +217,6 @@ NS_IMETHODIMP nsXPCComponents_Interfaces
 NS_IMETHODIMP nsXPCComponents_Interfaces::GetManager(nsIInterfaceInfoManager * *aManager)
 {
     *aManager = mManager;
-    NS_IF_ADDREF(*aManager);
     return NS_OK;
 }
 NS_IMETHODIMP nsXPCComponents_Interfaces::SetManager(nsIInterfaceInfoManager * aManager)
@@ -423,6 +422,7 @@ nsXPCComponents_Interfaces::CanSetProper
 /***************************************************************************/
 
 class nsXPCComponents_InterfacesByID :
+            public XPCOMGCFinalizedObject,
             public nsIScriptableInterfacesByID,
             public nsIXPCScriptable,
             public nsIClassInfo
@@ -765,6 +765,7 @@ nsXPCComponents_InterfacesByID::CanSetPr
 
 
 class nsXPCComponents_Classes : 
+  public XPCOMGCFinalizedObject,
   public nsIXPCComponents_Classes,
   public nsIXPCScriptable,
   public nsIClassInfo
@@ -1020,6 +1021,7 @@ nsXPCComponents_Classes::NewResolve(nsIX
 /***************************************************************************/
 
 class nsXPCComponents_ClassesByID :
+  public XPCOMGCFinalizedObject,
   public nsIXPCComponents_ClassesByID,
   public nsIXPCScriptable,
   public nsIClassInfo
@@ -1294,6 +1296,7 @@ nsXPCComponents_ClassesByID::NewResolve(
 // cached once (unlike ContractIDs, CLSIDs, and IIDs)
 
 class nsXPCComponents_Results :
+  public XPCOMGCFinalizedObject,
   public nsIXPCComponents_Results,
   public nsIXPCScriptable,
   public nsIClassInfo
@@ -1519,6 +1522,7 @@ nsXPCComponents_Results::NewResolve(nsIX
 // JavaScript Constructor for nsIJSID objects (Components.ID)
 
 class nsXPCComponents_ID :
+  public XPCOMGCFinalizedObject,
   public nsIXPCComponents_ID,
   public nsIXPCScriptable,
   public nsIClassInfo
@@ -1746,6 +1750,7 @@ nsXPCComponents_ID::HasInstance(nsIXPCon
 // JavaScript Constructor for nsIXPCException objects (Components.Exception)
 
 class nsXPCComponents_Exception :
+  public XPCOMGCFinalizedObject,
   public nsIXPCComponents_Exception,
   public nsIXPCScriptable,
   public nsIClassInfo
@@ -2031,6 +2036,7 @@ nsXPCComponents_Exception::HasInstance(n
     { 0x8f, 0x61, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } }
 
 class nsXPCConstructor :
+  public XPCOMGCFinalizedObject,
   public nsIXPCConstructor,
   public nsIXPCScriptable,
   public nsIClassInfo
@@ -2159,8 +2165,8 @@ nsXPCConstructor::nsXPCConstructor(nsIJS
                                    nsIJSIID* aInterfaceID,
                                    const char* aInitializer)
 {
-    NS_IF_ADDREF(mClassID = aClassID);
-    NS_IF_ADDREF(mInterfaceID = aInterfaceID);
+    mClassID = aClassID;
+    mInterfaceID = aInterfaceID;
     mInitializer = aInitializer ?
         (char*) nsMemory::Clone(aInitializer, strlen(aInitializer)+1) :
         nsnull;
@@ -2178,7 +2184,7 @@ NS_IMETHODIMP
 NS_IMETHODIMP
 nsXPCConstructor::GetClassID(nsIJSCID * *aClassID)
 {
-    NS_IF_ADDREF(*aClassID = mClassID);
+    *aClassID = mClassID;
     return NS_OK;
 }
 
@@ -2186,7 +2192,7 @@ NS_IMETHODIMP
 NS_IMETHODIMP
 nsXPCConstructor::GetInterfaceID(nsIJSIID * *aInterfaceID)
 {
-    NS_IF_ADDREF(*aInterfaceID = mInterfaceID);
+    *aInterfaceID = mInterfaceID;
     return NS_OK;
 }
 
@@ -2305,6 +2311,7 @@ nsXPCConstructor::CallOrConstruct(nsIXPC
 // JavaScript Constructor for nsIXPCConstructor objects (Components.Constructor)
 
 class nsXPCComponents_Constructor :
+  public XPCOMGCFinalizedObject,
   public nsIXPCComponents_Constructor,
   public nsIXPCScriptable,
   public nsIClassInfo
@@ -2648,7 +2655,8 @@ nsXPCComponents_Constructor::HasInstance
 
 /***************************************************************************/
 // Javascript constructor for the sandbox object
-class nsXPCComponents_utils_Sandbox : public nsIXPCComponents_utils_Sandbox,
+class nsXPCComponents_utils_Sandbox : public XPCOMGCFinalizedObject,
+                                      public nsIXPCComponents_utils_Sandbox,
                                       public nsIXPCScriptable
 {
 public:
@@ -2672,6 +2680,7 @@ private:
 };
 
 class nsXPCComponents_Utils :
+            public XPCOMGCFinalizedObject,
             public nsIXPCComponents_Utils,
             public nsIXPCScriptable
 #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
@@ -2721,7 +2730,7 @@ nsXPCComponents_Utils::GetSandbox(nsIXPC
         *aSandbox = nsnull;
         return NS_ERROR_OUT_OF_MEMORY;
     }
-    NS_ADDREF(*aSandbox = mSandbox);
+    *aSandbox = mSandbox;
     return NS_OK;
 }
 
@@ -3198,7 +3207,6 @@ xpc_CreateSandboxObject(JSContext * cx, 
             return NS_ERROR_XPC_UNEXPECTED;
         }
 
-        NS_ADDREF(tmp);
     }
 
     rv = xpc->InitClasses(cx, sandbox);
@@ -3331,7 +3339,7 @@ nsXPCComponents_utils_Sandbox::CallOrCon
 #endif /* XPCONNECT_STANDALONE */
 }
 
-class ContextHolder : public nsISupports
+class ContextHolder : public XPCOMGCFinalizedObject, public nsISupports
 {
 public:
     ContextHolder(JSContext *aOuterCx, JSObject *aSandbox);
@@ -3612,7 +3620,6 @@ nsXPCComponents_Utils::GetWeakReference(
         return NS_ERROR_OUT_OF_MEMORY;
     ref->Init();
     *_retval = ref;
-    NS_ADDREF(*_retval);
     return NS_OK;
 }
 
@@ -3837,9 +3844,7 @@ NS_IMETHODIMP nsXPCComponents::Get##_n(_
             *a##_n = nsnull; \
             return NS_ERROR_OUT_OF_MEMORY; \
         } \
-        NS_ADDREF(m##_n); \
     } \
-    NS_ADDREF(m##_n); \
     *a##_n = m##_n; \
     return NS_OK; \
 }
@@ -4004,7 +4009,7 @@ nsXPCComponents::AttachNewComponentsObje
 
     nsCOMPtr<nsIXPCComponents> cholder(components);
 
-    AutoMarkingNativeInterfacePtr iface(ccx);
+    XPCNativeInterface* iface;
     iface = XPCNativeInterface::GetNewOrUsed(ccx, &NS_GET_IID(nsIXPCComponents));
 
     if(!iface)
diff --git a/js/src/xpconnect/src/xpccontext.cpp b/js/src/xpconnect/src/xpccontext.cpp
--- a/js/src/xpconnect/src/xpccontext.cpp
+++ b/js/src/xpconnect/src/xpccontext.cpp
@@ -71,7 +71,6 @@ XPCContext::XPCContext(XPCJSRuntime* aRu
 {
     MOZ_COUNT_CTOR(XPCContext);
 
-    PR_INIT_CLIST(&mScopes);
     for(const char** p =  XPC_ARG_FORMATTER_FORMAT_STRINGS; *p; p++)
         JS_AddArgumentFormatter(mJSContext, *p, XPC_JSArgumentFormatter);
 }
@@ -81,15 +80,6 @@ XPCContext::~XPCContext()
     MOZ_COUNT_DTOR(XPCContext);
     NS_IF_RELEASE(mException);
     NS_IF_RELEASE(mSecurityManager);
-
-    // Iterate over our scopes and tell them that we have been destroyed
-    for(PRCList *scopeptr = PR_NEXT_LINK(&mScopes);
-        scopeptr != &mScopes;
-        scopeptr = PR_NEXT_LINK(scopeptr))
-    {
-        XPCWrappedNativeScope *scope = (XPCWrappedNativeScope *)scopeptr;
-        scope->SetContext(nsnull);
-    }
 
     // we do not call JS_RemoveArgumentFormatter because we now only
     // delete XPCContext *after* the underlying JSContext is dead
diff --git a/js/src/xpconnect/src/xpcconvert.cpp b/js/src/xpconnect/src/xpcconvert.cpp
--- a/js/src/xpconnect/src/xpcconvert.cpp
+++ b/js/src/xpconnect/src/xpcconvert.cpp
@@ -1095,7 +1095,7 @@ XPCConvert::NativeInterface2JSObject(XPC
         if(!xpcscope)
             return JS_FALSE;
 
-        AutoMarkingNativeInterfacePtr iface(ccx);
+        XPCNativeInterface* iface;
         iface = XPCNativeInterface::GetNewOrUsed(ccx, iid);
         if(!iface)
             return JS_FALSE;
@@ -1256,7 +1256,6 @@ XPCConvert::NativeInterface2JSObject(XPC
                     return JS_FALSE;
                 }
 
-                NS_ADDREF(objHolder);
                 NS_RELEASE(wrapper);
                 *dest = objHolder;
                 return JS_TRUE;
@@ -1307,7 +1306,6 @@ XPCConvert::JSObject2NativeInterface(XPC
             // is the underlying object the right interface?
             if(wrappedNative->GetIID().Equals(*iid))
             {
-                NS_ADDREF(iface);
                 *dest = iface;
                 return JS_TRUE;
             }
@@ -1427,7 +1425,6 @@ XPCConvert::JSValToXPCException(XPCCallC
             {
                 // just pass through the exception (with extra ref and all)
                 nsIException* temp = iface;
-                NS_ADDREF(temp);
                 *exceptn = temp;
                 return NS_OK;
             }
@@ -1603,7 +1600,6 @@ XPCConvert::JSErrorToXPCException(XPCCal
         if(!data)
             return NS_ERROR_OUT_OF_MEMORY;
 
-        NS_ADDREF(data);
         data->Init(bestMessage.get(),
                    NS_ConvertASCIItoUTF16(report->filename).get(),
                    (const PRUnichar *)report->uclinebuf, report->lineno,
diff --git a/js/src/xpconnect/src/xpcinlines.h b/js/src/xpconnect/src/xpcinlines.h
--- a/js/src/xpconnect/src/xpcinlines.h
+++ b/js/src/xpconnect/src/xpcinlines.h
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  *
  * ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
@@ -575,31 +575,6 @@ XPCNativeSet::MatchesSetUpToInterface(co
     return JS_FALSE;
 }
 
-inline void XPCNativeSet::Mark()
-{
-    if(IsMarked())
-        return;
-
-    XPCNativeInterface* const * pp = mInterfaces;
-
-    for(int i = (int) mInterfaceCount; i > 0; i--, pp++)
-        (*pp)->Mark();
-
-    MarkSelfOnly();
-}
-
-#ifdef DEBUG
-inline void XPCNativeSet::ASSERT_NotMarked()
-{
-    NS_ASSERTION(!IsMarked(), "bad");
-
-    XPCNativeInterface* const * pp = mInterfaces;
-
-    for(int i = (int) mInterfaceCount; i > 0; i--, pp++)
-        NS_ASSERTION(!(*pp)->IsMarked(), "bad");
-}
-#endif
-
 /***************************************************************************/
 
 inline
@@ -656,16 +631,6 @@ XPCWrappedNativeTearOff::IsIDispatch() c
 
 #endif
 
-inline
-XPCWrappedNativeTearOff::~XPCWrappedNativeTearOff()
-{
-    NS_ASSERTION(!(GetInterface()||GetNative()||GetJSObject()), "tearoff not empty in dtor");
-#ifdef XPC_IDISPATCH_SUPPORT
-    if(IsIDispatch())
-        delete GetIDispatchInfo();
-#endif
-}
-
 /***************************************************************************/
 
 inline JSBool
@@ -678,36 +643,6 @@ XPCWrappedNative::HasInterfaceNoQI(const
 XPCWrappedNative::HasInterfaceNoQI(const nsIID& iid)
 {
     return nsnull != GetSet()->FindInterfaceWithIID(iid);
-}
-
-inline void
-XPCWrappedNative::SweepTearOffs()
-{
-    XPCWrappedNativeTearOffChunk* chunk;
-    for(chunk = &mFirstChunk; chunk; chunk = chunk->mNextChunk)
-    {
-        XPCWrappedNativeTearOff* to = chunk->mTearOffs;
-        for(int i = XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK; i > 0; i--, to++)
-        {
-            JSBool marked = to->IsMarked();
-            to->Unmark();
-            if(marked)
-                continue;
-
-            // If this tearoff does not have a live dedicated JSObject,
-            // then let's recycle it.
-            if(!to->GetJSObject())
-            {
-                nsISupports* obj = to->GetNative();
-                if(obj)
-                {
-                    obj->Release();
-                    to->SetNative(nsnull);
-                }
-                to->SetInterface(nsnull);
-            }
-        }
-    }
 }
 
 /***************************************************************************/
diff --git a/js/src/xpconnect/src/xpcjsid.cpp b/js/src/xpconnect/src/xpcjsid.cpp
--- a/js/src/xpconnect/src/xpcjsid.cpp
+++ b/js/src/xpconnect/src/xpcjsid.cpp
@@ -225,7 +225,6 @@ nsJSID::NewID(const char* str)
     nsJSID* idObj = new nsJSID();
     if(idObj)
     {
-        NS_ADDREF(idObj);
         if(NS_FAILED(idObj->Initialize(str)))
             NS_RELEASE(idObj);
     }
@@ -259,7 +258,7 @@ nsJSID::NewID(const nsID& id)
 // helper is not sufficient to convey the information that we don't want
 // static properties enumerated on the shared proto.
 
-class SharedScriptableHelperForJSIID : public nsIXPCScriptable
+class SharedScriptableHelperForJSIID : public XPCOMGCFinalizedObject, public nsIXPCScriptable
 {
 public:
     NS_DECL_ISUPPORTS
@@ -289,7 +288,6 @@ NS_METHOD GetSharedScriptableHelperForJS
 {
     if(language == nsIProgrammingLanguage::JAVASCRIPT)
     {
-        NS_IF_ADDREF(gSharedScriptableHelperForJSIID);
         *helper = gSharedScriptableHelperForJSIID;
     }
     else
@@ -358,7 +356,6 @@ JSBool xpc_InitJSxIDClassObjects()
     gSharedScriptableHelperForJSIID = new SharedScriptableHelperForJSIID();
     if(!gSharedScriptableHelperForJSIID)
         goto return_failure;
-    NS_ADDREF(gSharedScriptableHelperForJSIID);
 
     gClassObjectsWereInited = JS_TRUE;
     return JS_TRUE;
@@ -480,7 +477,6 @@ nsJSIID::NewID(nsIInterfaceInfo* aInfo)
         return nsnull;
 
     nsJSIID* idObj = new nsJSIID(aInfo);
-    NS_IF_ADDREF(idObj);
     return idObj;
 }
 
@@ -494,7 +490,7 @@ nsJSIID::NewResolve(nsIXPConnectWrappedN
 {
     XPCCallContext ccx(JS_CALLER, cx);
 
-    AutoMarkingNativeInterfacePtr iface(ccx);
+    XPCNativeInterface* iface;
 
     const nsIID* iid;
     mInfo->GetIIDShared(&iid);
@@ -536,7 +532,7 @@ nsJSIID::Enumerate(nsIXPConnectWrappedNa
 
     XPCCallContext ccx(JS_CALLER, cx);
 
-    AutoMarkingNativeInterfacePtr iface(ccx);
+    XPCNativeInterface* iface;
 
     const nsIID* iid;
     mInfo->GetIIDShared(&iid);
@@ -597,7 +593,7 @@ nsJSIID::HasInstance(nsIXPConnectWrapped
         // Otherwise, we'll end up Querying the native object to be sure.
         XPCCallContext ccx(JS_CALLER, cx);
 
-        AutoMarkingNativeInterfacePtr iface(ccx);
+        XPCNativeInterface* iface;
         iface = XPCNativeInterface::GetNewOrUsed(ccx, iid);
 
         if(iface && other_wrapper->FindTearOff(ccx, iface))
@@ -712,7 +708,6 @@ nsJSCID::NewID(const char* str)
     if(idObj)
     {
         PRBool success = PR_FALSE;
-        NS_ADDREF(idObj);
 
         if(str[0] == '{')
         {
diff --git a/js/src/xpconnect/src/xpcjsruntime.cpp b/js/src/xpconnect/src/xpcjsruntime.cpp
--- a/js/src/xpconnect/src/xpcjsruntime.cpp
+++ b/js/src/xpconnect/src/xpcjsruntime.cpp
@@ -83,30 +83,6 @@ struct JSDyingJSObjectData
     nsVoidArray* array;
 };
 
-#if 0
-// Let's pretend this is unnecessary (it probably is)
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-WrappedJSDyingJSObjectFinder(JSDHashTable *table, JSDHashEntryHdr *hdr,
-                uint32 number, void *arg)
-{
-    JSDyingJSObjectData* data = (JSDyingJSObjectData*) arg;
-    nsXPCWrappedJS* wrapper = ((JSObject2WrappedJSMap::Entry*)hdr)->value;
-    NS_ASSERTION(wrapper, "found a null JS wrapper!");
-
-    // walk the wrapper chain and find any whose JSObject is to be finalized
-    while(wrapper)
-    {
-        if(wrapper->IsSubjectToFinalization())
-        {
-            if(JS_IsAboutToBeFinalized(data->cx, wrapper->GetJSObject()))
-                data->array->AppendElement(wrapper);
-        }
-        wrapper = wrapper->GetNextWrapper();
-    }
-    return JS_DHASH_NEXT;
-}
-#endif
-
 struct CX_AND_XPCRT_Data
 {
     JSContext* cx;
@@ -118,29 +94,15 @@ NativeInterfaceGC(JSDHashTable *table, J
                   uint32 number, void *arg)
 {
     CX_AND_XPCRT_Data* data = (CX_AND_XPCRT_Data*) arg;
-    ((IID2NativeInterfaceMap::Entry*)hdr)->value->
-            DealWithDyingGCThings(data->cx, data->rt);
-    return JS_DHASH_NEXT;
-}
 
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-NativeInterfaceSweeper(JSDHashTable *table, JSDHashEntryHdr *hdr,
-                       uint32 number, void *arg)
-{
-    CX_AND_XPCRT_Data* data = (CX_AND_XPCRT_Data*) arg;
     XPCNativeInterface* iface = ((IID2NativeInterfaceMap::Entry*)hdr)->value;
+    iface->DealWithDyingGCThings(data->cx, data->rt);
+
     if(iface->IsMarked())
     {
-        iface->Unmark();
         return JS_DHASH_NEXT;
     }
 
-#ifdef XPC_REPORT_NATIVE_INTERFACE_AND_SET_FLUSHING
-    printf("- Destroying XPCNativeInterface for %s\n",
-            JS_GetStringBytes(JSVAL_TO_STRING(iface->GetName())));
-#endif
-
-    XPCNativeInterface::DestroyInstance(data->cx, data->rt, iface);
     return JS_DHASH_REMOVE;
 }
 
@@ -160,27 +122,15 @@ NativeUnMarkedSetRemover(JSDHashTable *t
 }
 
 JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-NativeSetSweeper(JSDHashTable *table, JSDHashEntryHdr *hdr,
-                 uint32 number, void *arg)
+NativeSetGC(JSDHashTable *table, JSDHashEntryHdr *hdr,
+            uint32 number, void *arg)
 {
     XPCNativeSet* set = ((NativeSetMap::Entry*)hdr)->key_value;
-    if(set->IsMarked())
+    if(NS_GetGC()->GetMark(set))
     {
-        set->Unmark();
         return JS_DHASH_NEXT;
     }
 
-#ifdef XPC_REPORT_NATIVE_INTERFACE_AND_SET_FLUSHING
-    printf("- Destroying XPCNativeSet for:\n");
-    PRUint16 count = set->GetInterfaceCount();
-    for(PRUint16 k = 0; k < count; k++)
-    {
-        XPCNativeInterface* iface = set->GetInterfaceAt(k);
-        printf("    %s\n",JS_GetStringBytes(JSVAL_TO_STRING(iface->GetName())));
-    }
-#endif
-
-    XPCNativeSet::DestroyInstance(set);
     return JS_DHASH_REMOVE;
 }
 
@@ -219,17 +169,6 @@ DyingProtoKiller(JSDHashTable *table, JS
         (XPCWrappedNativeProto*)((JSDHashEntryStub*)hdr)->key;
     delete proto;
     return JS_DHASH_REMOVE;
-}
-
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-DetachedWrappedNativeProtoMarker(JSDHashTable *table, JSDHashEntryHdr *hdr,
-                                 uint32 number, void *arg)
-{
-    XPCWrappedNativeProto* proto = 
-        (XPCWrappedNativeProto*)((JSDHashEntryStub*)hdr)->key;
-
-    proto->Mark();
-    return JS_DHASH_NEXT;
 }
 
 // GCCallback calls are chained
@@ -285,24 +224,6 @@ JSBool XPCJSRuntime::GCCallback(JSContex
                     self->mThreadRunningGC = PR_GetCurrentThread();
                 }
 
-                dyingWrappedJSArray = &self->mWrappedJSToReleaseArray;
-
-                {
-                    JSDyingJSObjectData data = {cx, dyingWrappedJSArray};
-
-                    // Add any wrappers whose JSObjects are to be finalized to
-                    // this array. Note that this is a nsVoidArray because
-                    // we do not want to be changing the refcount of these wrappers.
-                    // We add them to the array now and Release the array members
-                    // later to avoid the posibility of doing any JS GCThing
-                    // allocations during the gc cycle.
-#if 0
-                    // let's pretend this is unnecessary (it probably is)
-                    self->mWrappedJSMap->
-                        Enumerate(WrappedJSDyingJSObjectFinder, &data);
-#endif
-                }
-
                 // Do cleanup in NativeInterfaces. This part just finds 
                 // member cloned function objects that are about to be 
                 // collected. It does not deal with collection of interfaces or
@@ -312,7 +233,9 @@ JSBool XPCJSRuntime::GCCallback(JSContex
                 self->mIID2NativeInterfaceMap->
                     Enumerate(NativeInterfaceGC, &data);
 
-                // Find dying scopes...
+                self->mNativeSetMap->
+                    Enumerate(NativeSetGC, nsnull);
+
                 XPCWrappedNativeScope::FinishedMarkPhaseOfGC(cx, self);
 
                 self->mDoingFinalization = JS_TRUE;
@@ -349,15 +272,6 @@ JSBool XPCJSRuntime::GCCallback(JSContex
                 int ifacesBefore = (int) self->mIID2NativeInterfaceMap->Count();
 #endif
 
-                // We use this occasion to mark and sweep NativeInterfaces,
-                // NativeSets, and the WrappedNativeJSClasses...
-
-                // Do the marking...
-                XPCWrappedNativeScope::MarkAllWrappedNativesAndProtos();
-
-                self->mDetachedWrappedNativeProtoMap->
-                    Enumerate(DetachedWrappedNativeProtoMarker, nsnull);
-
                 // Mark the sets used in the call contexts. There is a small
                 // chance that a wrapper's set will change *while* a call is
                 // happening which uses that wrapper's old interfface set. So,
@@ -382,28 +296,6 @@ JSBool XPCJSRuntime::GCCallback(JSContex
                         {
                             // Mark those AutoMarkingPtr lists!
                             thread->MarkAutoRootsAfterJSFinalize();
-
-                            XPCCallContext* ccxp = thread->GetCallContext();
-                            while(ccxp)
-                            {
-                                // Deal with the strictness of callcontext that
-                                // complains if you ask for a set when
-                                // it is in a state where the set could not
-                                // possibly be valid.
-                                if(ccxp->CanGetSet())
-                                {
-                                    XPCNativeSet* set = ccxp->GetSet();
-                                    if(set)
-                                        set->Mark();
-                                }
-                                if(ccxp->CanGetInterface())
-                                {
-                                    XPCNativeInterface* iface = ccxp->GetInterface();
-                                    if(iface)
-                                        iface->Mark();
-                                }
-                                ccxp = ccxp->GetPrevCallContext();
-                            }
                         }
                     }
                 }
@@ -422,18 +314,6 @@ JSBool XPCJSRuntime::GCCallback(JSContex
                 self->mClassInfo2NativeSetMap->
                     Enumerate(NativeUnMarkedSetRemover, nsnull);
 
-                self->mNativeSetMap->
-                    Enumerate(NativeSetSweeper, nsnull);
-
-                CX_AND_XPCRT_Data data = {cx, self};
-
-                self->mIID2NativeInterfaceMap->
-                    Enumerate(NativeInterfaceSweeper, &data);
-
-#ifdef DEBUG
-                XPCWrappedNativeScope::ASSERT_NoInterfaceSetsAreMarked();
-#endif
-
 #ifdef XPC_REPORT_NATIVE_INTERFACE_AND_SET_FLUSHING
                 int setsAfter = (int) self->mNativeSetMap->Count();
                 int ifacesAfter = (int) self->mIID2NativeInterfaceMap->Count();
@@ -445,81 +325,6 @@ JSBool XPCJSRuntime::GCCallback(JSContex
                        ifacesBefore, ifacesBefore - ifacesAfter, ifacesAfter);
                 printf("--------------------------------------------------------------\n");
 #endif
-
-                // Sweep scopes needing cleanup
-                XPCWrappedNativeScope::FinishedFinalizationPhaseOfGC(cx);
-
-                // Now we are going to recycle any unused WrappedNativeTearoffs.
-                // We do this by iterating all the live callcontexts (on all
-                // threads!) and marking the tearoffs in use. And then we
-                // iterate over all the WrappedNative wrappers and sweep their
-                // tearoffs.
-                //
-                // This allows us to perhaps minimize the growth of the
-                // tearoffs. And also makes us not hold references to interfaces
-                // on our wrapped natives that we are not actually using.
-                //
-                // XXX We may decide to not do this on *every* gc cycle.
-
-                // Skip this part if XPConnect is shutting down. We get into
-                // bad locking problems with the thread iteration otherwise.
-                if(!self->GetXPConnect()->IsShuttingDown())
-                {
-                    PRLock* threadLock = XPCPerThreadData::GetLock();
-                    if(threadLock)
-                    {
-                        // Do the marking...
-                        
-                        { // scoped lock
-                            nsAutoLock lock(threadLock);
-
-                            XPCPerThreadData* iterp = nsnull;
-                            XPCPerThreadData* thread;
-
-                            while(nsnull != (thread =
-                                     XPCPerThreadData::IterateThreads(&iterp)))
-                            {
-                                XPCCallContext* ccxp = thread->GetCallContext();
-                                while(ccxp)
-                                {
-                                    // Deal with the strictness of callcontext that
-                                    // complains if you ask for a tearoff when
-                                    // it is in a state where the tearoff could not
-                                    // possibly be valid.
-                                    if(ccxp->CanGetTearOff())
-                                    {
-                                        XPCWrappedNativeTearOff* to = 
-                                            ccxp->GetTearOff();
-                                        if(to)
-                                            to->Mark();
-                                    }
-                                    ccxp = ccxp->GetPrevCallContext();
-                                }
-                            }
-                        }
-    
-                        // Do the sweeping...
-                        XPCWrappedNativeScope::SweepAllWrappedNativeTearOffs();
-                    }
-                }
-
-                // Now we need to kill the 'Dying' XPCWrappedNativeProtos.
-                // We transfered these native objects to this table when their
-                // JSObject's were finalized. We did not destroy them immediately
-                // at that point because the ordering of JS finalization is not
-                // deterministic and we did not yet know if any wrappers that
-                // might still be referencing the protos where still yet to be
-                // finalized and destroyed. We *do* know that the protos'
-                // JSObjects would not have been finalized if there were any
-                // wrappers that referenced the proto but where not themselves
-                // slated for finalization in this gc cycle. So... at this point
-                // we know that any and all wrappers that might have been
-                // referencing the protos in the dying list are themselves dead.
-                // So, we can safely delete all the protos in the list.
-
-                self->mDyingWrappedNativeProtoMap->
-                    Enumerate(DyingProtoKiller, nsnull);
-
 
                 // mThreadRunningGC indicates that GC is running.
                 // Clear it and notify waiters.
@@ -534,35 +339,6 @@ JSBool XPCJSRuntime::GCCallback(JSContex
             }
             case JSGC_END:
             {
-                // NOTE that this event happens outside of the gc lock in
-                // the js engine. So this could be simultaneous with the
-                // events above.
-
-                // Do any deferred released of native objects.
-                nsVoidArray* array = &self->mNativesToReleaseArray;
-#ifdef XPC_TRACK_DEFERRED_RELEASES
-                printf("XPC - Begin deferred Release of %d nsISupports pointers\n",
-                       array->Count());
-#endif
-                while(1)
-                {
-                    nsISupports* obj;
-                    {
-                        PRInt32 count = array->Count();
-                        if(!count)
-                        {
-                            array->Compact();
-                            break;
-                        }
-                        obj = reinterpret_cast<nsISupports*>
-                            (array->ElementAt(count-1));
-                        array->RemoveElementAt(count-1);
-                    }
-                    NS_RELEASE(obj);
-                }
-#ifdef XPC_TRACK_DEFERRED_RELEASES
-                printf("XPC - End deferred Releases\n");
-#endif
                 break;
             }
             default:
@@ -799,11 +575,6 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
     // these jsids filled in later when we have a JSContext to work with.
     mStrIDs[0] = 0;
 
-    if(mJSRuntimeService)
-    {
-        NS_ADDREF(mJSRuntimeService);
-    }
-
     NS_ASSERTION(!gOldJSGCCallback, "XPCJSRuntime created more than once");
     gOldJSContextCallback = JS_SetContextCallback(gJSRuntime,
                                                   ContextCallback);
@@ -969,21 +740,6 @@ XPCJSRuntime::GenerateStringIDs(JSContex
         mStrJSVals[i] = STRING_TO_JSVAL(str);
     }
     return JS_TRUE;
-}
-
-JSBool
-XPCJSRuntime::DeferredRelease(nsISupports* obj)
-{
-    NS_ASSERTION(obj, "bad param");
-
-    if(!mNativesToReleaseArray.Count())
-    {
-        // This array sometimes has 1000's
-        // of entries, and usually has 50-200 entries. Avoid lots
-        // of incremental grows.  We compact it down when we're done.
-        mNativesToReleaseArray.SizeTo(256);
-    }
-    return mNativesToReleaseArray.AppendElement(obj);
 }
 
 /***************************************************************************/
diff --git a/js/src/xpconnect/src/xpcmaps.cpp b/js/src/xpconnect/src/xpcmaps.cpp
--- a/js/src/xpconnect/src/xpcmaps.cpp
+++ b/js/src/xpconnect/src/xpcmaps.cpp
@@ -199,6 +199,26 @@ Native2WrappedNativeMap::~Native2Wrapped
         JS_DHashTableDestroy(mTable);
 }
 
+// static
+JSDHashOperator
+Native2WrappedNativeMap::DyingUnmapper(JSDHashTable *table,
+                                       JSDHashEntryHdr *hdr,
+                                       uint32 number,
+                                       void *arg)
+{
+    Entry *entry = static_cast<Entry*>(hdr);
+
+    if(NS_GetGC()->GetMark(entry->value))
+    {
+        NS_ASSERTION(NS_GetGC()->GetMark(entry->key),
+                     "XPCWrappedNative should keep native alive!");
+
+        return JS_DHASH_NEXT;
+    }
+
+    return JS_DHASH_REMOVE;
+}
+
 /***************************************************************************/
 // implement IID2WrappedJSClassMap...
 
@@ -322,6 +342,25 @@ ClassInfo2WrappedNativeProtoMap::~ClassI
 {
     if(mTable)
         JS_DHashTableDestroy(mTable);
+}
+
+JSDHashOperator
+ClassInfo2WrappedNativeProtoMap::DyingUnmapper(JSDHashTable *table,
+                                               JSDHashEntryHdr *hdr,
+                                               uint32 number,
+                                               void *arg)
+{
+    Entry *entry = static_cast<Entry*>(hdr);
+
+    if(NS_GetGC()->GetMark(entry->value))
+    {
+        NS_ASSERTION(NS_GetGC()->GetMark(entry->key),
+                     "XPCWrappedNativeProto should keep related classinfo alive!");
+
+        return JS_DHASH_NEXT;
+    }
+
+    return JS_DHASH_REMOVE;
 }
 
 /***************************************************************************/
@@ -785,4 +824,35 @@ WrappedNative2WrapperMap::AddLink(JSObje
     return PR_TRUE;
 }
 
+// static
+JSDHashOperator
+WrappedNative2WrapperMap::DyingUnmapper(JSDHashTable *table,
+                                        JSDHashEntryHdr *hdr,
+                                        uint32 number,
+                                        void *arg)
+{
+    Entry *entry = static_cast<Entry*>(hdr);
+
+    if(NS_GetGC()->GetMark(entry->key))
+    {
+#ifdef DEBUG
+        for (Link *l = &entry->value; l; l = static_cast<Link*>(l->next)) {
+            NS_ASSERTION(NS_GetGC()->GetMark(l->obj),
+                         "In WrappedNative2WrapperMap::DyingUnmapper key was marked but not value.");
+        }
+#endif
+        
+        return JS_DHASH_NEXT;
+    }
+
+#ifdef DEBUG
+    for (Link *l = &entry->value; l; l = static_cast<Link*>(l->next)) {
+        NS_ASSERTION(!NS_GetGC()->GetMark(l->obj),
+                     "In WrappedNative2WrappedMap::DyingUnmapper value was marked but not key.");
+    }
+#endif
+
+    return JS_DHASH_REMOVE;
+}
+
 /***************************************************************************/
diff --git a/js/src/xpconnect/src/xpcmaps.h b/js/src/xpconnect/src/xpcmaps.h
--- a/js/src/xpconnect/src/xpcmaps.h
+++ b/js/src/xpconnect/src/xpcmaps.h
@@ -214,6 +214,11 @@ public:
         JS_DHashTableOperate(mTable, wrapper->GetIdentityObject(), JS_DHASH_REMOVE);
     }
 
+    inline void UnmapDyingNatives()
+    {
+        JS_DHashTableEnumerate(mTable, DyingUnmapper, nsnull);
+    }
+
     inline uint32 Count() {return mTable->entryCount;}
     inline uint32 Enumerate(JSDHashEnumerator f, void *arg)
         {return JS_DHashTableEnumerate(mTable, f, arg);}
@@ -222,6 +227,11 @@ private:
 private:
     Native2WrappedNativeMap();    // no implementation
     Native2WrappedNativeMap(int size);
+
+    static JSDHashOperator DyingUnmapper(JSDHashTable *table,
+                                         JSDHashEntryHdr *hdr,
+                                         uint32 number,
+                                         void *arg);
 private:
     JSDHashTable *mTable;
 };
@@ -436,6 +446,11 @@ public:
         JS_DHashTableOperate(mTable, info, JS_DHASH_REMOVE);
     }
 
+    inline void UnmapDyingNatives()
+    {
+        JS_DHashTableEnumerate(mTable, DyingUnmapper, nsnull);
+    }
+
     inline uint32 Count() {return mTable->entryCount;}
     inline uint32 Enumerate(JSDHashEnumerator f, void *arg)
         {return JS_DHashTableEnumerate(mTable, f, arg);}
@@ -444,6 +459,12 @@ private:
 private:
     ClassInfo2WrappedNativeProtoMap();    // no implementation
     ClassInfo2WrappedNativeProtoMap(int size);
+
+    static JSDHashOperator DyingUnmapper(JSDHashTable *table,
+                                         JSDHashEntryHdr *hdr,
+                                         uint32 number,
+                                         void *arg);
+
 private:
     JSDHashTable *mTable;
 };
@@ -556,7 +577,6 @@ public:
             JS_DHashTableOperate(mTable, &iid, JS_DHASH_ADD);
         if(!entry)
             return nsnull;
-        NS_IF_ADDREF(obj);
         NS_IF_RELEASE(entry->value);
         entry->value = obj;
         entry->key = iid;
@@ -750,6 +770,11 @@ public:
         JS_DHashTableOperate(mTable, wrapper, JS_DHASH_REMOVE);
     }
 
+    inline void UnmapDyingNatives()
+    {
+        JS_DHashTableEnumerate(mTable, DyingUnmapper, nsnull);
+    }
+
     inline uint32 Count() {return mTable->entryCount;}
     inline uint32 Enumerate(JSDHashEnumerator f, void *arg)
         {return JS_DHashTableEnumerate(mTable, f, arg);}
@@ -760,6 +785,10 @@ private:
     WrappedNative2WrapperMap();    // no implementation
     WrappedNative2WrapperMap(int size);
 
+    static JSDHashOperator DyingUnmapper(JSDHashTable *table,
+                                         JSDHashEntryHdr *hdr,
+                                         uint32 number,
+                                         void *arg);
 private:
     JSDHashTable *mTable;
 };
diff --git a/js/src/xpconnect/src/xpcprivate.h b/js/src/xpconnect/src/xpcprivate.h
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -442,7 +442,8 @@ const PRBool OBJ_IS_GLOBAL = PR_TRUE;
 const PRBool OBJ_IS_GLOBAL = PR_TRUE;
 const PRBool OBJ_IS_NOT_GLOBAL = PR_FALSE;
 
-class nsXPConnect : public nsIXPConnect,
+class nsXPConnect : public XPCOMGCFinalizedObject,
+                    public nsIXPConnect,
                     public nsIThreadObserver,
                     public nsSupportsWeakReference
 {
@@ -617,8 +618,6 @@ public:
     XPCContext* GetXPCContext(JSContext* cx);
     XPCContext* SyncXPCContextList(JSContext* cx = nsnull);
 
-    JSBool DeferredRelease(nsISupports* obj);
-
     JSBool GetDoingFinalization() const {return mDoingFinalization;}
 
     // Mapping of often used strings to jsid atoms that live 'forever'.
@@ -783,13 +782,11 @@ public:
 
     nsresult GetException(nsIException** e)
         {
-            NS_IF_ADDREF(mException);
             *e = mException;
             return NS_OK;
         }
     void SetException(nsIException* e)
         {
-            NS_IF_ADDREF(e);
             NS_IF_RELEASE(mException);
             mException = e;
         }
@@ -832,8 +829,6 @@ public:
         }
 
     void DebugDump(PRInt16 depth);
-    void AddScope(PRCList *scope) { PR_INSERT_AFTER(scope, &mScopes); }
-    void RemoveScope(PRCList *scope) { PR_REMOVE_LINK(scope); }
 
     ~XPCContext();
 
@@ -851,9 +846,6 @@ private:
     LangType mCallingLangType;
     PRUint16 mSecurityManagerFlags;
     JSPackedBool mMarked;
-
-    // A linked list of scopes to notify when we are destroyed.
-    PRCList mScopes;
 };
 
 /***************************************************************************/
@@ -1155,7 +1147,7 @@ xpc_TraceForValidWrapper(JSTracer *trc, 
 /***************************************************************************/
 // XPCWrappedNativeScope is one-to-one with a JS global object.
 
-class XPCWrappedNativeScope : public PRCList
+class XPCWrappedNativeScope : XPCOMGCFinalizedObject, MMgc::GCFinalizable
 {
 public:
 
@@ -1200,6 +1192,12 @@ public:
 
     void RemoveWrappedNativeProtos();
 
+    /**
+     * Called at the end of marking: enumerates the wrappednatives in the map
+     * and removes those which are about to be finalized.
+     */
+    inline void UnmapDyingNatives();
+
     static XPCWrappedNativeScope*
     FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
                         JSBool OKIfNotInitialized = JS_FALSE);
@@ -1210,22 +1208,8 @@ public:
     static void
     FinishedMarkPhaseOfGC(JSContext* cx, XPCJSRuntime* rt);
 
-    static void
-    FinishedFinalizationPhaseOfGC(JSContext* cx);
-
-    static void
-    MarkAllWrappedNativesAndProtos();
-
     static nsresult
     ClearAllWrappedNativeSecurityPolicies(XPCCallContext& ccx);
-
-#ifdef DEBUG
-    static void
-    ASSERT_NoInterfaceSetsAreMarked();
-#endif
-
-    static void
-    SweepAllWrappedNativeTearOffs();
 
     static void
     DebugDumpAllScopes(PRInt16 depth);
@@ -1236,13 +1220,10 @@ public:
     JSBool
     IsValid() const {return mRuntime != nsnull;}
 
-    static JSBool
-    IsDyingScope(XPCWrappedNativeScope *scope);
-
     void SetComponents(nsXPCComponents* aComponents);
     void SetGlobal(XPCCallContext& ccx, JSObject* aGlobal);
 
-    static void InitStatics() { gScopes = nsnull; gDyingScopes = nsnull; }
+    static void InitStatics() { gScopes = nsnull; }
 
     XPCContext *GetContext() { return mContext; }
     void SetContext(XPCContext *xpcc) { mContext = nsnull; }
@@ -1258,13 +1239,10 @@ protected:
     XPCWrappedNativeScope(XPCCallContext& ccx, JSObject* aGlobal);
     virtual ~XPCWrappedNativeScope();
 
-    static void KillDyingScopes();
-
     XPCWrappedNativeScope(); // not implemented
 
 private:
     static XPCWrappedNativeScope* gScopes;
-    static XPCWrappedNativeScope* gDyingScopes;
 
     XPCJSRuntime*                    mRuntime;
     Native2WrappedNativeMap*         mWrappedNativeMap;
@@ -1400,7 +1378,7 @@ private:
 
 // Tight. No virtual methods.
 
-class XPCNativeInterface
+class XPCNativeInterface : XPCOMGCObject
 {
 public:
     static XPCNativeInterface* GetNewOrUsed(XPCCallContext& ccx,
@@ -1424,7 +1402,7 @@ public:
                               const XPCNativeMember* member) const;
 
     PRUint16 GetMemberCount() const
-        {NS_ASSERTION(!IsMarked(), "bad"); return mMemberCount;}
+        { return mMemberCount;}
     XPCNativeMember* GetMemberAt(PRUint16 i)
         {NS_ASSERTION(i < mMemberCount, "bad index"); return &mMembers[i];}
 
@@ -1434,17 +1412,10 @@ public:
 
 #define XPC_NATIVE_IFACE_MARK_FLAG ((PRUint16)JS_BIT(15)) // only high bit of 16 is set
 
-    void Mark()     {mMemberCount |= XPC_NATIVE_IFACE_MARK_FLAG;}
-    void Unmark()   {mMemberCount &= ~XPC_NATIVE_IFACE_MARK_FLAG;}
     JSBool IsMarked() const
-                    {return 0 != (mMemberCount & XPC_NATIVE_IFACE_MARK_FLAG);}
-
-    // NOP. This is just here to make the AutoMarkingPtr code compile.
-    inline void TraceJS(JSTracer* trc) {}
-    inline void AutoTrace(JSTracer* trc) {}
-
-    static void DestroyInstance(JSContext* cx, XPCJSRuntime* rt,
-                                XPCNativeInterface* inst);
+    {
+        return 0 != NS_GetGC()->GetMark(this);
+    }
 
 protected:
     static XPCNativeInterface* NewInstance(XPCCallContext& ccx,
@@ -1454,12 +1425,21 @@ protected:
     XPCNativeInterface(nsIInterfaceInfo* aInfo, jsval aName)
         : mInfo(aInfo), mName(aName), mMemberCount(0)
                           {MOZ_COUNT_CTOR(XPCNativeInterface);}
-    ~XPCNativeInterface() {MOZ_COUNT_DTOR(XPCNativeInterface);}
-
-    void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
 
     XPCNativeInterface(const XPCNativeInterface& r); // not implemented
     XPCNativeInterface& operator= (const XPCNativeInterface& r); // not implemented
+
+    static void* operator new(size_t size, size_t memberCount)
+    {
+        if (memberCount > 1)
+            size += (memberCount - 1) * sizeof(XPCNativeMember);
+        return XPCOMGCObject::operator new(size);
+    }
+
+    static void operator delete(void *obj)
+    {
+        MMgc::GCObject::operator delete(obj);
+    }
 
 private:
     nsCOMPtr<nsIInterfaceInfo> mInfo;
@@ -1521,7 +1501,7 @@ private:
 /***************************************************************************/
 // XPCNativeSet represents an ordered collection of XPCNativeInterface pointers.
 
-class XPCNativeSet
+class XPCNativeSet : XPCOMGCObject
 {
 public:
     static XPCNativeSet* GetNewOrUsed(XPCCallContext& ccx, const nsIID* iid);
@@ -1566,12 +1546,6 @@ public:
 
 #define XPC_NATIVE_SET_MARK_FLAG ((PRUint16)JS_BIT(15)) // only high bit of 16 is set
 
-    inline void Mark();
-
-    // NOP. This is just here to make the AutoMarkingPtr code compile.
-    inline void TraceJS(JSTracer* trc) {}
-    inline void AutoTrace(JSTracer* trc) {}
-
 private:
     void MarkSelfOnly() {mInterfaceCount |= XPC_NATIVE_SET_MARK_FLAG;}
 public:
@@ -1579,13 +1553,7 @@ public:
     JSBool IsMarked() const
                   {return 0 != (mInterfaceCount & XPC_NATIVE_SET_MARK_FLAG);}
 
-#ifdef DEBUG
-    inline void ASSERT_NotMarked();
-#endif
-
     void DebugDump(PRInt16 depth);
-
-    static void DestroyInstance(XPCNativeSet* inst);
 
 protected:
     static XPCNativeSet* NewInstance(XPCCallContext& ccx,
@@ -1594,9 +1562,7 @@ protected:
     static XPCNativeSet* NewInstanceMutate(XPCNativeSet*       otherSet,
                                            XPCNativeInterface* newInterface,
                                            PRUint16            position);
-    XPCNativeSet()  {MOZ_COUNT_CTOR(XPCNativeSet);}
-    ~XPCNativeSet() {MOZ_COUNT_DTOR(XPCNativeSet);}
-    void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
+    static void* operator new(size_t size, PRUint16 interfaceCount);
 
 private:
     PRUint16                mMemberCount;
@@ -1722,7 +1688,7 @@ private:
 // XPCNativeScriptableInfo is used to hold the nsIXPCScriptable state for a
 // given class or instance.
 
-class XPCNativeScriptableInfo
+class XPCNativeScriptableInfo : XPCOMGCObject
 {
 public:
     static XPCNativeScriptableInfo*
@@ -1752,10 +1718,8 @@ protected:
 protected:
     XPCNativeScriptableInfo(nsIXPCScriptable* scriptable = nsnull,
                             XPCNativeScriptableShared* shared = nsnull)
-        : mCallback(scriptable), mShared(shared)
-                               {MOZ_COUNT_CTOR(XPCNativeScriptableInfo);}
-public:
-    ~XPCNativeScriptableInfo() {MOZ_COUNT_DTOR(XPCNativeScriptableInfo);}
+        : mCallback(scriptable), mShared(shared) {}
+
 private:
 
     // disable copy ctor and assignment
@@ -1796,7 +1760,7 @@ public:
     SetFlags(const XPCNativeScriptableFlags& flags)  {mFlags = flags;}
 
 private:
-    nsCOMPtr<nsIXPCScriptable>  mCallback;
+    nsIXPCScriptable*           mCallback;
     XPCNativeScriptableFlags    mFlags;
 };
 
@@ -1804,7 +1768,7 @@ private:
 // XPCWrappedNativeProto hold the additional (potentially shared) wrapper data
 // for XPCWrappedNative whose native objects expose nsIClassInfo.
 
-class XPCWrappedNativeProto
+class XPCWrappedNativeProto : XPCOMGCObject
 {
 public:
     static XPCWrappedNativeProto*
@@ -1869,29 +1833,6 @@ public:
 
     void DebugDump(PRInt16 depth);
 
-    void TraceJS(JSTracer* trc)
-    {
-        if(mJSProtoObject)
-        {
-            JS_CALL_OBJECT_TRACER(trc, mJSProtoObject,
-                                  "XPCWrappedNativeProto::mJSProtoObject");
-        }
-        if(mScriptableInfo && JS_IsGCMarkingTracer(trc))
-            mScriptableInfo->Mark();
-    }
-
-    // NOP. This is just here to make the AutoMarkingPtr code compile.
-    inline void AutoTrace(JSTracer* trc) {}
-
-    // Yes, we *do* need to mark the mScriptableInfo in both cases.
-    void Mark() const
-        {mSet->Mark(); 
-         if(mScriptableInfo) mScriptableInfo->Mark();}
-
-#ifdef DEBUG
-    void ASSERT_SetNotMarked() const {mSet->ASSERT_NotMarked();}
-#endif
-
     ~XPCWrappedNativeProto();
 
 protected:
@@ -1928,6 +1869,9 @@ private:
 // XPCWrappedNativeTearOff represents the info needed to make calls to one
 // interface on the underlying native object of a XPCWrappedNative.
 
+// XPCWrappedNativeTearOffs are always allocated within the
+// XPCWrappedNativeTearOffChunk linked-list structure.
+
 class XPCWrappedNativeTearOff
 {
 public:
@@ -1945,18 +1889,6 @@ public:
 
     void JSObjectFinalized() {SetJSObject(nsnull);}
 
-    XPCWrappedNativeTearOff()
-        : mInterface(nsnull), mNative(nsnull), mJSObject(nsnull) {}
-    ~XPCWrappedNativeTearOff();
-
-    // NOP. This is just here to make the AutoMarkingPtr code compile.
-    inline void TraceJS(JSTracer* trc) {}
-    inline void AutoTrace(JSTracer* trc) {}
-
-    void Mark()       {mJSObject = (JSObject*)(((jsword)mJSObject) | 1);}
-    void Unmark()     {mJSObject = (JSObject*)(((jsword)mJSObject) & ~1);}
-    JSBool IsMarked() const {return (JSBool)(((jsword)mJSObject) & 1);}
-
 #ifdef XPC_IDISPATCH_SUPPORT
     enum JSObject_flags
     {
@@ -1968,6 +1900,15 @@ public:
     XPCDispInterface*   GetIDispatchInfo() const;
 #endif
 private:
+    XPCWrappedNativeTearOff()
+        : mInterface(nsnull), mNative(nsnull), mJSObject(nsnull) 
+    {
+        ASSERT_GCObject(this);
+    }
+    ~XPCWrappedNativeTearOff() { }
+
+    friend class XPCWrappedNativeTearOffChunk;
+
     XPCWrappedNativeTearOff(const XPCWrappedNativeTearOff& r); // not implemented
     XPCWrappedNativeTearOff& operator= (const XPCWrappedNativeTearOff& r); // not implemented
 
@@ -1994,9 +1935,19 @@ friend class XPCWrappedNative;
 friend class XPCWrappedNative;
 private:
     XPCWrappedNativeTearOffChunk() : mNextChunk(nsnull) {}
-    ~XPCWrappedNativeTearOffChunk() {delete mNextChunk;}
+    ~XPCWrappedNativeTearOffChunk() {}
+
+    static void* operator new(size_t size)
+    {
+        return XPCOMGCObject::operator new(size);
+    }
 
 private:
+    static void operator delete(void *o)
+    {
+        NS_NOTREACHED("Don't delete me!");
+    }
+
     XPCWrappedNativeTearOff mTearOffs[XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK];
     XPCWrappedNativeTearOffChunk* mNextChunk;
 };
@@ -2005,7 +1956,7 @@ private:
 // XPCWrappedNative the wrapper around one instance of a native xpcom object
 // to be used from JavaScript.
 
-class XPCWrappedNative : public nsIXPConnectWrappedNative
+class XPCWrappedNative : public XPCOMGCFinalizedObject, public nsIXPConnectWrappedNative
 {
 public:
     NS_DECL_ISUPPORTS
@@ -2188,49 +2139,12 @@ public:
                                          XPCNativeInterface* aInterface,
                                          JSBool needJSObject = JS_FALSE,
                                          nsresult* pError = nsnull);
-    void Mark() const
-    {
-        mSet->Mark();
-        if(mScriptableInfo) mScriptableInfo->Mark();
-        if(HasProto()) GetProto()->Mark();
-    }
-
-    // Yes, we *do* need to mark the mScriptableInfo in both cases.
-    inline void TraceJS(JSTracer* trc)
-    {
-        if(mScriptableInfo && JS_IsGCMarkingTracer(trc))
-            mScriptableInfo->Mark();
-        if(HasProto()) GetProto()->TraceJS(trc);
-        if(mWrapper)
-            JS_CALL_OBJECT_TRACER(trc, mWrapper, "XPCWrappedNative::mWrapper");
-        TraceOtherWrapper(trc);
-    }
-
-    inline void AutoTrace(JSTracer* trc)
-    {
-        // If this got called, we're being kept alive by someone who really
-        // needs us alive and whole.  Do not let our mFlatJSObject go away.
-        // This is the only time we should be tracing our mFlatJSObject,
-        // normally somebody else is doing that. Be careful not to trace the
-        // bogus JSVAL_ONE value we can have during init, though.
-        if(mFlatJSObject && mFlatJSObject != (JSObject*)JSVAL_ONE)
-        {
-            JS_CALL_OBJECT_TRACER(trc, mFlatJSObject,
-                                  "XPCWrappedNative::mFlatJSObject");
-        }
-    }
 
 #ifdef DEBUG
-    void ASSERT_SetsNotMarked() const
-        {mSet->ASSERT_NotMarked();
-         if(HasProto()){GetProto()->ASSERT_SetNotMarked();}}
-
     int DEBUG_CountOfTearoffChunks() const
         {int i = 0; const XPCWrappedNativeTearOffChunk* to;
          for(to = &mFirstChunk; to; to = to->mNextChunk) {i++;} return i;}
 #endif
-
-    inline void SweepTearOffs();
 
     // Returns a string that shuld be free'd using JS_smprintf_free (or null).
     char* ToString(XPCCallContext& ccx,
@@ -2326,7 +2240,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIXPCWrap
 // nsXPCWrappedJSClass represents the sharable factored out common code and
 // data for nsXPCWrappedJS instances for the same interface type.
 
-class nsXPCWrappedJSClass : public nsIXPCWrappedJSClass
+class nsXPCWrappedJSClass : public XPCOMGCFinalizedObject, public nsIXPCWrappedJSClass
 {
     // all the interface method declarations...
     NS_DECL_ISUPPORTS
@@ -2424,7 +2338,8 @@ private:
 // nsXPCWrappedJS objects are chained together to represent the various
 // interface on the single underlying (possibly aggregate) JSObject.
 
-class nsXPCWrappedJS : protected nsAutoXPTCStub,
+class nsXPCWrappedJS : public XPCOMGCFinalizedObject,
+                       protected nsAutoXPTCStub,
                        public nsIXPConnectWrappedJS,
                        public nsSupportsWeakReference,
                        public nsIPropertyBag,
@@ -2493,7 +2408,8 @@ private:
 
 /***************************************************************************/
 
-class XPCJSObjectHolder : public nsIXPConnectJSObjectHolder,
+class XPCJSObjectHolder : public XPCOMGCFinalizedObject,
+                          public nsIXPConnectJSObjectHolder,
                           public XPCRootSetElem
 {
 public:
@@ -2528,7 +2444,7 @@ private:
 ****************************************************************************
 ***************************************************************************/
 
-class xpcProperty : public nsIProperty
+class xpcProperty : public XPCOMGCFinalizedObject, public nsIProperty
 {
 public:
   NS_DECL_ISUPPORTS
@@ -2542,7 +2458,7 @@ private:
     nsCOMPtr<nsIVariant> mValue;
 };
 
-class xpcPropertyBagEnumerator : public nsISimpleEnumerator
+class xpcPropertyBagEnumerator : public XPCOMGCFinalizedObject, public nsISimpleEnumerator
 {
 public:
     NS_DECL_ISUPPORTS
@@ -2761,7 +2677,7 @@ private:
 /***************************************************************************/
 
 class nsXPCException :
-            public nsIXPCException
+            public XPCOMGCFinalizedObject, public nsIXPCException
 {
 public:
     NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCEXCEPTION_CID)
@@ -2818,7 +2734,7 @@ extern void xpc_DestroyJSxIDClassObjects
 extern void xpc_DestroyJSxIDClassObjects();
 
 
-class nsJSID : public nsIJSID
+class nsJSID : public XPCOMGCFinalizedObject, public nsIJSID
 {
 public:
     NS_DEFINE_STATIC_CID_ACCESSOR(NS_JS_ID_CID)
@@ -2853,7 +2769,7 @@ protected:
 
 // nsJSIID
 
-class nsJSIID : public nsIJSIID, public nsIXPCScriptable
+class nsJSIID : public XPCOMGCFinalizedObject, public nsIJSIID, public nsIXPCScriptable
 #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
           , public nsISecurityCheckedComponent
 #endif
@@ -2883,7 +2799,7 @@ private:
 
 // nsJSCID
 
-class nsJSCID : public nsIJSCID, public nsIXPCScriptable
+class nsJSCID : public XPCOMGCFinalizedObject, public nsIJSCID, public nsIXPCScriptable
 {
 public:
     NS_DECL_ISUPPORTS
@@ -2961,7 +2877,7 @@ private:
 { 0x05bae29d, 0x8aef, 0x486d, \
   { 0x84, 0xaa, 0x53, 0xf4, 0x8f, 0x14, 0x68, 0x11 } }
 
-class nsXPCJSContextStackIterator : public nsIJSContextStackIterator
+class nsXPCJSContextStackIterator : public XPCOMGCFinalizedObject, public nsIJSContextStackIterator
 {
 public:
     NS_DECL_ISUPPORTS
@@ -3003,7 +2919,6 @@ public:
         if(EnsureExceptionManager())
             return mExceptionManager->GetCurrentException(aException);
 
-        NS_IF_ADDREF(mException);
         *aException = mException;
         return NS_OK;
     }
@@ -3013,7 +2928,6 @@ public:
         if(EnsureExceptionManager())
             return mExceptionManager->SetCurrentException(aException);
 
-        NS_IF_ADDREF(aException);
         NS_IF_RELEASE(mException);
         mException = aException;
         return NS_OK;
@@ -3142,7 +3056,8 @@ private:
 { 0xff8c4d10, 0x3194, 0x11d3, \
     { 0x98, 0x85, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
 
-class nsXPCThreadJSContextStackImpl : public nsIThreadJSContextStack,
+class nsXPCThreadJSContextStackImpl : public XPCOMGCFinalizedObject,
+                                      public nsIThreadJSContextStack,
                                       public nsSupportsWeakReference
 {
 public:
@@ -3177,7 +3092,8 @@ private:
 #ifndef XPCONNECT_STANDALONE
 #include "nsIScriptSecurityManager.h"
 
-class BackstagePass : public nsIScriptObjectPrincipal,
+class BackstagePass : public XPCOMGCFinalizedObject,
+                      public nsIScriptObjectPrincipal,
                       public nsIXPCScriptable,
                       public nsIClassInfo
 {
@@ -3219,7 +3135,8 @@ public:
 
 #endif
 
-class nsJSRuntimeServiceImpl : public nsIJSRuntimeService,
+class nsJSRuntimeServiceImpl : public XPCOMGCFinalizedObject,
+                               public nsIJSRuntimeService,
                                public nsSupportsWeakReference
 {
  public:
@@ -3245,7 +3162,8 @@ class nsJSRuntimeServiceImpl : public ns
 /***************************************************************************/
 // 'Components' object
 
-class nsXPCComponents : public nsIXPCComponents,
+class nsXPCComponents : public XPCOMGCFinalizedObject,
+                        public nsIXPCComponents,
                         public nsIXPCScriptable,
                         public nsIClassInfo
 #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
@@ -3291,6 +3209,7 @@ private:
 /***************************************************************************/
 
 class nsXPCComponents_Interfaces :
+            public XPCOMGCFinalizedObject,
             public nsIScriptableInterfaces,
             public nsIXPCScriptable,
             public nsIClassInfo
@@ -3348,7 +3267,7 @@ xpc_InstallJSDebuggerKeywordHandler(JSRu
 
 // Definition of nsScriptError, defined here because we lack a place to put
 // XPCOM objects associated with the JavaScript engine.
-class nsScriptError : public nsIScriptError {
+class nsScriptError : public XPCOMGCFinalizedObject, public nsIScriptError {
 public:
     nsScriptError();
 
@@ -3649,11 +3568,6 @@ protected:                              
 
 // Use the macro above to define our AutoMarking types...
 
-DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingNativeInterfacePtr, XPCNativeInterface)
-DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingNativeSetPtr, XPCNativeSet)
-DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativePtr, XPCWrappedNative)
-DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeTearOffPtr, XPCWrappedNativeTearOff)
-DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeProtoPtr, XPCWrappedNativeProto)
 DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingJSVal, XPCMarkableJSVal)
                                     
 #define DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(class_, type_)                    \
@@ -3708,9 +3622,6 @@ protected:                              
     PRUint32 mCount;                                                         \
 };
 
-DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(AutoMarkingNativeInterfacePtrArrayPtr,
-                                   XPCNativeInterface)
-    
 // Note: It looked like I would need one of these AutoMarkingPtr types for
 // XPCNativeScriptableInfo in order to manage marking its 
 // XPCNativeScriptableShared member during construction. But AFAICT we build
@@ -3744,7 +3655,7 @@ extern char * xpc_CheckAccessList(const 
     {0x1809fd50, 0x91e8, 0x11d5, \
       { 0x90, 0xf9, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } }
 
-class XPCVariant : public nsIVariant
+class XPCVariant : public XPCOMGCFinalizedObject, public nsIVariant
 {
 public:
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -3816,7 +3727,7 @@ public:
 #define PRINCIPALHOLDER_IID \
 {0xbf109f49, 0xf94a, 0x43d8, {0x93, 0xdb, 0xe4, 0x66, 0x49, 0xc5, 0xd9, 0x7d}}
 
-class PrincipalHolder : public nsIScriptObjectPrincipal
+class PrincipalHolder : public XPCOMGCFinalizedObject, public nsIScriptObjectPrincipal
 {
 public:
     NS_DECLARE_STATIC_IID_ACCESSOR(PRINCIPALHOLDER_IID)
diff --git a/js/src/xpconnect/src/xpcwrappedjs.cpp b/js/src/xpconnect/src/xpcwrappedjs.cpp
--- a/js/src/xpconnect/src/xpcwrappedjs.cpp
+++ b/js/src/xpconnect/src/xpcwrappedjs.cpp
@@ -59,7 +59,6 @@ nsXPCWrappedJS::AggregatedQueryInterface
     // once in QueryInterface and once in DelegatedQueryInterface.
     if(aIID.Equals(NS_GET_IID(nsIXPConnectWrappedJS)))
     {
-        NS_ADDREF(this);
         *aInstancePtr = (void*) static_cast<nsIXPConnectWrappedJS*>(this);
         return NS_OK;
     }
@@ -83,7 +82,6 @@ nsXPCWrappedJS::QueryInterface(REFNSIID 
     // from us without recurring into a call to the outer's QI!
     if(aIID.Equals(NS_GET_IID(nsIXPConnectWrappedJS)))
     {
-        NS_ADDREF(this);
         *aInstancePtr = (void*) static_cast<nsIXPConnectWrappedJS*>(this);
         return NS_OK;
     }
@@ -158,7 +156,6 @@ nsXPCWrappedJS::GetNewOrUsed(XPCCallCont
         if((nsnull != (wrapper = root->Find(aIID))) ||
            (nsnull != (wrapper = root->FindInherited(aIID))))
         {
-            NS_ADDREF(wrapper);
             goto return_wrapper;
         }
     }
@@ -256,10 +253,6 @@ nsXPCWrappedJS::nsXPCWrappedJS(XPCCallCo
     InitStub(GetClass()->GetIID());
 
     // intensionally do double addref - see Release().
-    NS_ADDREF_THIS();
-    NS_ADDREF_THIS();
-    NS_ADDREF(aClass);
-    NS_IF_ADDREF(mOuter);
 }
 
 nsXPCWrappedJS::~nsXPCWrappedJS()
@@ -305,16 +298,8 @@ nsXPCWrappedJS::Unlink()
     NS_IF_RELEASE(mClass);
     if (mOuter)
     {
-        XPCJSRuntime* rt = nsXPConnect::GetRuntime();
-        if (rt && rt->GetThreadRunningGC())
-        {
-            rt->DeferredRelease(mOuter);
-            mOuter = nsnull;
-        }
-        else
-        {
-            NS_RELEASE(mOuter);
-        }
+        mClass = nsnull;
+        mOuter = nsnull;
     }
 }
 
@@ -361,7 +346,6 @@ nsXPCWrappedJS::GetInterfaceInfo(nsIInte
 
     if(!(*info = GetClass()->GetInterfaceInfo()))
         return NS_ERROR_UNEXPECTED;
-    NS_ADDREF(*info);
     return NS_OK;
 }
 
diff --git a/js/src/xpconnect/src/xpcwrappednative.cpp b/js/src/xpconnect/src/xpcwrappednative.cpp
--- a/js/src/xpconnect/src/xpcwrappednative.cpp
+++ b/js/src/xpconnect/src/xpcwrappednative.cpp
@@ -240,14 +240,12 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
     // after we have Init'd the wrapper but *before* we add it to the hashtable.
     // This would cause the mSet to get collected and we'd later crash. I've
     // *seen* this happen.
-    AutoMarkingWrappedNativePtr wrapper(ccx);
+    XPCWrappedNative* wrapper;
 
     Native2WrappedNativeMap* map = Scope->GetWrappedNativeMap();
     {   // scoped lock
         XPCAutoLock lock(mapLock);
         wrapper = map->Find(identity);
-        if(wrapper)
-            wrapper->AddRef();
     }
 
     if(wrapper)
@@ -342,8 +340,6 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
         {   // scoped lock
             XPCAutoLock lock(mapLock);
             wrapper = map->Find(identity);
-            if(wrapper)
-                wrapper->AddRef();
         }
 
         if(wrapper)
@@ -360,7 +356,7 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
         }
     }
 
-    AutoMarkingWrappedNativeProtoPtr proto(ccx);
+    XPCWrappedNativeProto* proto = nsnull;
 
     // If there is ClassInfo (and we are not building a wrapper for the
     // nsIClassInfo interface) then we use a wrapper that needs a prototype.
@@ -381,7 +377,7 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
     }
     else
     {
-        AutoMarkingNativeSetPtr set(ccx);
+        XPCNativeSet* set;
         set = XPCNativeSet::GetNewOrUsed(ccx, nsnull, Interface, 0);
 
         if(!set)
@@ -394,7 +390,6 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
         DEBUG_ReportShadowedMembers(set, wrapper, nsnull);
     }
 
-    NS_ADDREF(wrapper);
 
     NS_ASSERTION(!XPCNativeWrapper::IsNativeWrapper(parent),
                  "XPCNativeWrapper being used to parent XPCWrappedNative?");
@@ -408,7 +403,6 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
     if(!wrapper->FindTearOff(ccx, Interface, JS_FALSE, &rv))
     {
         // Second reference will be released by the FlatJSObject's finializer.
-        wrapper->Release();
         NS_ASSERTION(NS_FAILED(rv), "returning NS_OK on failure");
         return rv;
     }
@@ -441,7 +435,6 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
         }
         else if(wrapper2 != wrapper)
         {
-            NS_ADDREF(wrapper2);
             wrapperToKill = wrapper;
             wrapper = wrapper2;
         }
@@ -449,8 +442,6 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
 
     if(wrapperToKill)
     {
-        // Second reference will be released by the FlatJSObject's finializer.
-        wrapperToKill->Release();
     }
     else if(wrapper)
     {
@@ -481,10 +472,6 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
                     map->Remove(wrapper);
                 }
 
-                // This would be a good place to tell the wrapper not to remove
-                // itself from the map when it dies... See bug 429442.
-
-                wrapper->Release();
                 return rv;
             }
         }
@@ -533,7 +520,6 @@ XPCWrappedNative::GetUsedOnly(XPCCallCon
             *resultWrapper = nsnull;
             return NS_OK;
         }
-        NS_ADDREF(wrapper);
     }
 
     nsresult rv;
@@ -557,7 +543,7 @@ XPCWrappedNative::XPCWrappedNative(nsISu
       mScriptableInfo(nsnull),
       mWrapper(nsnull)
 {
-    NS_ADDREF(mIdentity = aIdentity);
+    mIdentity = aIdentity;
 
     NS_ASSERTION(mMaybeProto, "bad ctor param");
     NS_ASSERTION(mSet, "bad ctor param");
@@ -576,7 +562,7 @@ XPCWrappedNative::XPCWrappedNative(nsISu
       mScriptableInfo(nsnull),
       mWrapper(nsnull)
 {
-    NS_ADDREF(mIdentity = aIdentity);
+    mIdentity = aIdentity;
 
     NS_ASSERTION(aScope, "bad ctor param");
     NS_ASSERTION(aSet, "bad ctor param");
@@ -588,45 +574,17 @@ XPCWrappedNative::~XPCWrappedNative()
 {
     DEBUG_TrackDeleteWrapper(this);
 
-    XPCWrappedNativeProto* proto = GetProto();
+#if 0 // XXXbsmedberg: I'd like this, but we can't refer to members
+    XPCWrappedNativeScope* scope = GetScope();
+    if (NS_GetGC()->GetMark(scope))
+    {
+        Native2WrappedNativeMap* map = GetScope()->GetWrappedNativeMap();
+        NS_ASSERTION(!map->Find(mIdentity),
+                     "Finalizing an XPCWrappedNative without unmapping it");
+    }
+#endif
 
-    if(mScriptableInfo &&
-       (!HasProto() ||
-        (proto && proto->GetScriptableInfo() != mScriptableInfo)))
-    {
-        delete mScriptableInfo;
-    }
-
-    XPCWrappedNativeScope *scope = GetScope();
-    if(scope)
-    {
-        Native2WrappedNativeMap* map = scope->GetWrappedNativeMap();
-
-        // scoped lock
-        XPCAutoLock lock(GetRuntime()->GetMapLock());
-
-        // Post-1.9 we should not remove this wrapper from the map if it is
-        // uninitialized.
-        map->Remove(this);
-    }
-
-    if(mIdentity)
-    {
-        XPCJSRuntime* rt = GetRuntime();
-        if(rt && rt->GetDoingFinalization())
-        {
-            if(!rt->DeferredRelease(mIdentity))
-            {
-                NS_WARNING("Failed to append object for deferred release.");
-                // XXX do we really want to do this???
-                NS_RELEASE(mIdentity);
-            }
-        }
-        else
-        {
-            NS_RELEASE(mIdentity);
-        }
-    }
+    mIdentity = nsnull;
 }
 
 // This is factored out so that it can be called publicly 
@@ -943,31 +901,7 @@ XPCWrappedNative::FlatJSObjectFinalized(
             }
 
             // We also need to release any native pointers held...
-            nsISupports* obj = to->GetNative();
-            if(obj)
-            {
-#ifdef XP_WIN
-                // Try to detect free'd pointer
-                NS_ASSERTION(*(int*)obj != 0xdddddddd, "bad pointer!");
-                NS_ASSERTION(*(int*)obj != 0,          "bad pointer!");
-#endif
-                XPCJSRuntime* rt = GetRuntime();
-                if(rt)
-                {
-                    if(!rt->DeferredRelease(obj))
-                    {
-                        NS_WARNING("Failed to append object for deferred release.");
-                        // XXX do we really want to do this???
-                        obj->Release();
-                    }
-                }
-                else
-                {
-                    obj->Release();
-                }
-                to->SetNative(nsnull);
-            }
-
+            to->SetNative(nsnull);
             to->SetInterface(nsnull);
         }
     }
@@ -994,17 +928,8 @@ XPCWrappedNative::FlatJSObjectFinalized(
     // This makes IsValid return false from now on...
     mFlatJSObject = nsnull;
 
-    NS_ASSERTION(mIdentity, "bad pointer!");
-#ifdef XP_WIN
-    // Try to detect free'd pointer
-    NS_ASSERTION(*(int*)mIdentity != 0xdddddddd, "bad pointer!");
-    NS_ASSERTION(*(int*)mIdentity != 0,          "bad pointer!");
-#endif
-
     // Note that it's not safe to touch mNativeWrapper here since it's
     // likely that it has already been finalized.
-
-    Release();
 }
 
 void
@@ -1120,8 +1045,8 @@ XPCWrappedNative::ReparentWrapperIfFound
         nsXPConnect* xpc = nsXPConnect::GetXPConnect();
         xpc->UpdateXOWs(ccx, wrapper, nsIXPConnect::XPC_XOW_CLEARSCOPE);
 
-        AutoMarkingWrappedNativeProtoPtr oldProto(ccx);
-        AutoMarkingWrappedNativeProtoPtr newProto(ccx);
+        XPCWrappedNativeProto* oldProto = nsnull;
+        XPCWrappedNativeProto* newProto = nsnull;
 
         if(wrapper->HasProto())
         {
@@ -1370,7 +1295,7 @@ XPCWrappedNative::ExtendSet(XPCCallConte
 
     if(!mSet->HasInterface(aInterface))
     {
-        AutoMarkingNativeSetPtr newSet(ccx);
+        XPCNativeSet* newSet;
         newSet = XPCNativeSet::GetNewOrUsed(ccx, mSet, aInterface,
                                             mSet->GetInterfaceCount());
         if(!newSet)
@@ -1441,13 +1366,11 @@ XPCWrappedNative::FindTearOff(XPCCallCon
             {
                 if(needJSObject && !to->GetJSObject())
                 {
-                    AutoMarkingWrappedNativeTearOffPtr tearoff(ccx, to);
                     rv = InitTearOffJSObject(ccx, to);
                     // During shutdown, we don't sweep tearoffs.  So make sure
                     // to unmark manually in case the auto-marker marked us.
                     // We shouldn't ever be getting here _during_ our
                     // Mark/Sweep cycle, so this should be safe.
-                    to->Unmark();
                     if(NS_FAILED(rv))
                         to = nsnull;
                 }
@@ -1475,12 +1398,7 @@ XPCWrappedNative::FindTearOff(XPCCallCon
 
     {
         // Scope keeps |tearoff| from leaking across the return_result: label
-        AutoMarkingWrappedNativeTearOffPtr tearoff(ccx, to);
         rv = InitTearOff(ccx, to, aInterface, needJSObject);
-        // During shutdown, we don't sweep tearoffs.  So make sure to unmark
-        // manually in case the auto-marker marked us.  We shouldn't ever be
-        // getting here _during_ our Mark/Sweep cycle, so this should be safe.
-        to->Unmark();
         if(NS_FAILED(rv))
             to = nsnull;
     }
@@ -2467,8 +2385,6 @@ done:
             }
             else if(dp->IsValAllocated())
                 nsMemory::Free(p);
-            else if(dp->IsValInterface())
-                ((nsISupports*)p)->Release();
             else if(dp->IsValDOMString())
                 ccx.DeleteString((nsAString*)p);
             else if(dp->IsValUTF8String())
@@ -2508,7 +2424,6 @@ NS_IMETHODIMP XPCWrappedNative::GetNativ
     // No need to QI here, we already have the correct nsISupports
     // vtable.
     *aNative = mIdentity;
-    NS_ADDREF(*aNative);
     return NS_OK;
 }
 
@@ -2540,7 +2455,6 @@ NS_IMETHODIMP XPCWrappedNative::GetXPCon
     if(IsValid())
     {
         nsIXPConnect* temp = GetRuntime()->GetXPConnect();
-        NS_IF_ADDREF(temp);
         *aXPConnect = temp;
     }
     else
@@ -2557,7 +2471,6 @@ NS_IMETHODIMP XPCWrappedNative::FindInte
     if(GetSet()->FindMember(name, &member, &iface) && iface)
     {
         nsIInterfaceInfo* temp = iface->GetInterfaceInfo();
-        NS_IF_ADDREF(temp);
         *_retval = temp;
     }
     else
@@ -2572,7 +2485,6 @@ NS_IMETHODIMP XPCWrappedNative::FindInte
     if(iface)
     {
         nsIInterfaceInfo* temp = iface->GetInterfaceInfo();
-        NS_IF_ADDREF(temp);
         *_retval = temp;
     }
     else
@@ -2599,8 +2511,8 @@ NS_IMETHODIMP XPCWrappedNative::RefreshP
     if(!GetFlatJSObject())
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
-    AutoMarkingWrappedNativeProtoPtr oldProto(ccx);
-    AutoMarkingWrappedNativeProtoPtr newProto(ccx);
+    XPCWrappedNativeProto* oldProto = nsnull;
+    XPCWrappedNativeProto* newProto = nsnull;
     
     oldProto = GetProto();
 
@@ -2616,7 +2528,7 @@ NS_IMETHODIMP XPCWrappedNative::RefreshP
 
     // If nothing needs to change then we're done.
 
-    if(newProto.get() == oldProto.get())
+    if(newProto == oldProto)
         return NS_OK;
 
     if(!JS_SetPrototype(ccx, GetFlatJSObject(), newProto->GetJSProtoObject()))
diff --git a/js/src/xpconnect/src/xpcwrappednativeinfo.cpp b/js/src/xpconnect/src/xpcwrappednativeinfo.cpp
--- a/js/src/xpconnect/src/xpcwrappednativeinfo.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativeinfo.cpp
@@ -216,7 +216,7 @@ XPCNativeInterface*
 XPCNativeInterface*
 XPCNativeInterface::GetNewOrUsed(XPCCallContext& ccx, const nsIID* iid)
 {
-    AutoMarkingNativeInterfacePtr iface(ccx);
+    XPCNativeInterface* iface;
     XPCJSRuntime* rt = ccx.GetRuntime();
 
     IID2NativeInterfaceMap* map = rt->GetIID2NativeInterfaceMap();
@@ -246,12 +246,10 @@ XPCNativeInterface::GetNewOrUsed(XPCCall
         if(!iface2)
         {
             NS_ERROR("failed to add our interface!");
-            DestroyInstance(ccx, rt, iface);
             iface = nsnull;
         }
         else if(iface2 != iface)
         {
-            DestroyInstance(ccx, rt, iface);
             iface = iface2;
         }
     }
@@ -263,7 +261,7 @@ XPCNativeInterface*
 XPCNativeInterface*
 XPCNativeInterface::GetNewOrUsed(XPCCallContext& ccx, nsIInterfaceInfo* info)
 {
-    AutoMarkingNativeInterfacePtr iface(ccx);
+    XPCNativeInterface* iface;
 
     const nsIID* iid;
     if(NS_FAILED(info->GetIIDShared(&iid)) || !iid)
@@ -293,12 +291,10 @@ XPCNativeInterface::GetNewOrUsed(XPCCall
         if(!iface2)
         {
             NS_ERROR("failed to add our interface!");
-            DestroyInstance(ccx, rt, iface);
             iface = nsnull;
         }
         else if(iface2 != iface)
         {
-            DestroyInstance(ccx, rt, iface);
             iface = iface2;
         }
     }
@@ -474,14 +470,7 @@ XPCNativeInterface::NewInstance(XPCCallC
 
     if(!failed)
     {
-        // Use placement new to create an object with the right amount of space
-        // to hold the members array
-        int size = sizeof(XPCNativeInterface);
-        if(realTotalCount > 1)
-            size += (realTotalCount - 1) * sizeof(XPCNativeMember);
-        void* place = new char[size];
-        if(place)
-            obj = new(place) XPCNativeInterface(aInfo, interfaceName);
+        obj = new(realTotalCount) XPCNativeInterface(aInfo, interfaceName);
 
         if(obj)
         {
@@ -497,15 +486,6 @@ XPCNativeInterface::NewInstance(XPCCallC
         delete [] members;
 
     return obj;
-}
-
-// static
-void
-XPCNativeInterface::DestroyInstance(JSContext* cx, XPCJSRuntime* rt,
-                                    XPCNativeInterface* inst)
-{
-    inst->~XPCNativeInterface();
-    delete [] (char*) inst;
 }
 
 const char*
@@ -536,9 +516,9 @@ XPCNativeSet*
 XPCNativeSet*
 XPCNativeSet::GetNewOrUsed(XPCCallContext& ccx, const nsIID* iid)
 {
-    AutoMarkingNativeSetPtr set(ccx);
+    XPCNativeSet* set = nsnull;
 
-    AutoMarkingNativeInterfacePtr iface(ccx);
+    XPCNativeInterface* iface;
     iface = XPCNativeInterface::GetNewOrUsed(ccx, iid);
     if(!iface)
         return nsnull;
@@ -570,12 +550,10 @@ XPCNativeSet::GetNewOrUsed(XPCCallContex
         if(!set2)
         {
             NS_ERROR("failed to add our set!");
-            DestroyInstance(set);
             set = nsnull;
         }
         else if(set2 != set)
         {
-            DestroyInstance(set);
             set = set2;
         }
     }
@@ -587,7 +565,7 @@ XPCNativeSet*
 XPCNativeSet*
 XPCNativeSet::GetNewOrUsed(XPCCallContext& ccx, nsIClassInfo* classInfo)
 {
-    AutoMarkingNativeSetPtr set(ccx);
+    XPCNativeSet* set = nsnull;
     XPCJSRuntime* rt = ccx.GetRuntime();
 
     ClassInfo2NativeSetMap* map = rt->GetClassInfo2NativeSetMap();
@@ -603,7 +581,8 @@ XPCNativeSet::GetNewOrUsed(XPCCallContex
         return set;
 
     nsIID** iidArray = nsnull;
-    AutoMarkingNativeInterfacePtrArrayPtr interfaceArray(ccx);
+
+    XPCNativeInterface** interfaceArray = nsnull;
     PRUint32 iidCount = 0;
 
     if(NS_FAILED(classInfo->GetInterfaces(&iidCount, &iidArray)))
@@ -623,12 +602,12 @@ XPCNativeSet::GetNewOrUsed(XPCCallContex
 
     if(iidCount)
     {
-        AutoMarkingNativeInterfacePtrArrayPtr
-            arr(ccx, new XPCNativeInterface*[iidCount], iidCount, PR_TRUE);
-        if (!arr)
+        interfaceArray = (XPCNativeInterface**)
+            NS_GetGC()->Alloc(sizeof(XPCNativeInterface*) * iidCount,
+                              MMgc::GC::kZero | MMgc::GC::kContainsPointers);
+
+        if (!interfaceArray)
             goto out;
-
-        interfaceArray = arr;
 
         XPCNativeInterface** currentInterface = interfaceArray;
         nsIID**              currentIID = iidArray;
@@ -672,13 +651,11 @@ XPCNativeSet::GetNewOrUsed(XPCCallContex
                     if(!set2)
                     {
                         NS_ERROR("failed to add our set!");
-                        DestroyInstance(set);
                         set = nsnull;
                         goto out;
                     }
                     if(set2 != set)
                     {
-                        DestroyInstance(set);
                         set = set2;
                     }
                 }
@@ -702,7 +679,7 @@ out:
     if(iidArray)
         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(iidCount, iidArray);
     if(interfaceArray)
-        delete [] interfaceArray.get();
+        NS_GetGC()->Free(interfaceArray);
 
     return set;
 }
@@ -729,7 +706,7 @@ XPCNativeSet::GetNewOrUsed(XPCCallContex
                            XPCNativeInterface* newInterface,
                            PRUint16 position)
 {
-    AutoMarkingNativeSetPtr set(ccx);
+    XPCNativeSet* set;
     XPCJSRuntime* rt = ccx.GetRuntime();
     NativeSetMap* map = rt->GetNativeSetMap();
     if(!map)
@@ -759,12 +736,10 @@ XPCNativeSet::GetNewOrUsed(XPCCallContex
         if(!set2)
         {
             NS_ERROR("failed to add our set!");
-            DestroyInstance(set);
             set = nsnull;
         }
         else if(set2 != set)
         {
-            DestroyInstance(set);
             set = set2;
         }
     }
@@ -800,14 +775,7 @@ XPCNativeSet::NewInstance(XPCCallContext
             slots--;
     }
 
-    // Use placement new to create an object with the right amount of space
-    // to hold the members array
-    int size = sizeof(XPCNativeSet);
-    if(slots > 1)
-        size += (slots - 1) * sizeof(XPCNativeInterface*);
-    void* place = new char[size];
-    if(place)
-        obj = new(place) XPCNativeSet();
+    obj = new(slots) XPCNativeSet();
 
     if(obj)
     {
@@ -849,12 +817,11 @@ XPCNativeSet::NewInstanceMutate(XPCNativ
 
     // Use placement new to create an object with the right amount of space
     // to hold the members array
-    int size = sizeof(XPCNativeSet);
+    PRUint16 slots = 1;
     if(otherSet)
-        size += otherSet->mInterfaceCount * sizeof(XPCNativeInterface*);
-    void* place = new char[size];
-    if(place)
-        obj = new(place) XPCNativeSet();
+        slots = otherSet->mInterfaceCount;
+    
+    obj = new(slots) XPCNativeSet();
 
     if(obj)
     {
@@ -885,12 +852,15 @@ XPCNativeSet::NewInstanceMutate(XPCNativ
     return obj;
 }
 
-// static
-void
-XPCNativeSet::DestroyInstance(XPCNativeSet* inst)
+void*
+XPCNativeSet::operator new(size_t size, PRUint16 interfaceCount)
 {
-    inst->~XPCNativeSet();
-    delete [] (char*) inst;
+    if (interfaceCount > 0)
+    {
+        size += (interfaceCount - 1) * sizeof(XPCNativeInterface*);
+    }
+
+    return XPCOMGCObject::operator new(size);
 }
 
 void
diff --git a/js/src/xpconnect/src/xpcwrappednativejsops.cpp b/js/src/xpconnect/src/xpcwrappednativejsops.cpp
--- a/js/src/xpconnect/src/xpcwrappednativejsops.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativejsops.cpp
@@ -208,7 +208,7 @@ XPC_WN_DoubleWrappedGetter(JSContext *cx
                     nsIXPCSecurityManager::HOOK_GET_PROPERTY);
     if(sm)
     {
-        AutoMarkingNativeInterfacePtr iface(ccx);
+        XPCNativeInterface *iface;
         iface = XPCNativeInterface::
                     GetNewOrUsed(ccx, &NS_GET_IID(nsIXPCWrappedJSObjectGetter));
 
@@ -324,7 +324,7 @@ DefinePropertyIfFound(XPCCallContext& cc
 
         if(wrapperToReflectInterfaceNames)
         {
-            AutoMarkingNativeInterfacePtr iface2(ccx);
+            XPCNativeInterface* iface2 = nsnull;
             XPCWrappedNativeTearOff* to;
             JSObject* jso;
 
@@ -664,45 +664,6 @@ TraceScopeJSObjects(JSTracer *trc, XPCWr
         JS_CALL_OBJECT_TRACER(trc, obj,
                               "XPCWrappedNativeScope::mPrototypeJSFunction");
     }
-}
-
-void
-xpc_TraceForValidWrapper(JSTracer *trc, XPCWrappedNative* wrapper)
-{
-    // NOTE: It might be nice to also do the wrapper->Mark() call here too
-    // when we are called during the marking phase of JS GC to mark the
-    // wrapper's and wrapper's proto's interface sets.
-    //
-    // We currently do that in the GC callback code. The reason we don't do that
-    // here is because the bits used in that marking do unpleasant things to the
-    // member counts in the interface and interface set objects. Those counts
-    // are used in the DealWithDyingGCThings calls that are part of this JS GC
-    // marking phase. By doing these calls later during our GC callback we 
-    // avoid that problem. Arguably this could be changed. But it ain't broke.
-    //
-    // However, we do need to call the wrapper's TraceJS so that
-    // it can be sure that its (potentially shared) JSClass is traced. The
-    // danger is that a live wrapper might not be in a wrapper map and thus
-    // won't be fully marked in the GC callback. This can happen if there is
-    // a security exception during wrapper creation or if during wrapper
-    // creation it is determined that the wrapper is not needed. In those cases
-    // the wrapper can never actually be used from JS code - so resources like
-    // the interface set will never be accessed. But the JS engine will still
-    // need to use the JSClass. So, some marking is required for protection.
-
-    wrapper->TraceJS(trc);
-     
-    TraceScopeJSObjects(trc, wrapper->GetScope());
-}
-
-JS_STATIC_DLL_CALLBACK(void)
-XPC_WN_Shared_Trace(JSTracer *trc, JSObject *obj)
-{
-    XPCWrappedNative* wrapper =
-        XPCWrappedNative::GetWrappedNativeOfJSObject(trc->context, obj);
-
-    if(wrapper && wrapper->IsValid())
-        xpc_TraceForValidWrapper(trc, wrapper);
 }
 
 JS_STATIC_DLL_CALLBACK(JSBool)
@@ -893,7 +854,7 @@ JSExtendedClass XPC_WN_NoHelper_JSClass 
         nsnull,                         // construct;
         nsnull,                         // xdrObject;
         nsnull,                         // hasInstance;
-        JS_CLASS_TRACE(XPC_WN_Shared_Trace), // mark/trace;
+        nsnull,                         // mark/trace;
         nsnull                          // spare;
     },
     XPC_WN_Equality,
@@ -1025,18 +986,6 @@ XPC_WN_Helper_Finalize(JSContext *cx, JS
         return;
     wrapper->GetScriptableCallback()->Finalize(wrapper, cx, obj);
     wrapper->FlatJSObjectFinalized(cx);
-}
-
-JS_STATIC_DLL_CALLBACK(void)
-XPC_WN_Helper_Trace(JSTracer *trc, JSObject *obj)
-{
-    XPCWrappedNative* wrapper =
-        XPCWrappedNative::GetWrappedNativeOfJSObject(trc->context, obj);
-    if(wrapper && wrapper->IsValid())
-    {
-        wrapper->GetScriptableCallback()->Trace(wrapper, trc, obj);
-        xpc_TraceForValidWrapper(trc, wrapper);
-    }
 }
 
 JS_STATIC_DLL_CALLBACK(JSBool)
@@ -1440,11 +1389,6 @@ XPCNativeScriptableShared::PopulateJSCla
 
     if(mFlags.WantHasInstance())
         mJSClass.base.hasInstance = XPC_WN_Helper_HasInstance;
-
-    if(mFlags.WantTrace())
-        mJSClass.base.mark = JS_CLASS_TRACE(XPC_WN_Helper_Trace);
-    else
-        mJSClass.base.mark = JS_CLASS_TRACE(XPC_WN_Shared_Trace);
 
     mJSClass.equality = XPC_WN_Equality;
     mJSClass.outerObject = XPC_WN_OuterObject;
diff --git a/js/src/xpconnect/src/xpcwrappednativeproto.cpp b/js/src/xpconnect/src/xpcwrappednativeproto.cpp
--- a/js/src/xpconnect/src/xpcwrappednativeproto.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativeproto.cpp
@@ -196,7 +196,7 @@ XPCWrappedNativeProto::GetNewOrUsed(XPCC
     NS_ASSERTION(Scope, "bad param");
     NS_ASSERTION(ClassInfo, "bad param");
 
-    AutoMarkingWrappedNativeProtoPtr proto(ccx);
+    XPCWrappedNativeProto* proto = nsnull;
     ClassInfo2WrappedNativeProtoMap* map;
     XPCLock* lock;
     JSBool shared;
@@ -235,7 +235,7 @@ XPCWrappedNativeProto::GetNewOrUsed(XPCC
         }
     }
 
-    AutoMarkingNativeSetPtr set(ccx);
+    XPCNativeSet* set;
     set = XPCNativeSet::GetNewOrUsed(ccx, ClassInfo);
     if(!set)
         return nsnull;
@@ -244,7 +244,6 @@ XPCWrappedNativeProto::GetNewOrUsed(XPCC
 
     if(!proto || !proto->Init(ccx, isGlobal, ScriptableCreateInfo))
     {
-        delete proto.get();
         return nsnull;
     }
 
diff --git a/js/src/xpconnect/src/xpcwrappednativescope.cpp b/js/src/xpconnect/src/xpcwrappednativescope.cpp
--- a/js/src/xpconnect/src/xpcwrappednativescope.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativescope.cpp
@@ -110,7 +110,6 @@ static void DEBUG_TrackScopeShutdown()
 /***************************************************************************/
 
 XPCWrappedNativeScope* XPCWrappedNativeScope::gScopes = nsnull;
-XPCWrappedNativeScope* XPCWrappedNativeScope::gDyingScopes = nsnull;
 
 // static
 XPCWrappedNativeScope*
@@ -161,8 +160,6 @@ XPCWrappedNativeScope::XPCWrappedNativeS
         // Grab the XPCContext associated with our context.
         mContext = mRuntime->GetContextMap()->Find(ccx.GetJSContext());
         NS_ASSERTION(mContext, "Context map is not synchronized");
-
-        mContext->AddScope(this);
     }
 
     if(aGlobal)
@@ -172,22 +169,9 @@ XPCWrappedNativeScope::XPCWrappedNativeS
     MOZ_COUNT_CTOR(XPCWrappedNativeScope);
 }
 
-// static
-JSBool
-XPCWrappedNativeScope::IsDyingScope(XPCWrappedNativeScope *scope)
-{
-    for(XPCWrappedNativeScope *cur = gDyingScopes; cur; cur = cur->mNext)
-    {
-        if(scope == cur)
-            return JS_TRUE;
-    }
-    return JS_FALSE;
-}
-
 void
 XPCWrappedNativeScope::SetComponents(nsXPCComponents* aComponents)
 {
-    NS_IF_ADDREF(aComponents);
     NS_IF_RELEASE(mComponents);
     mComponents = aComponents;
 }
@@ -304,6 +288,13 @@ XPCWrappedNativeScope::~XPCWrappedNative
 
     // We can do additional cleanup assertions here...
 
+#ifdef DEBUG
+    for (XPCWrappedNativeScope *cur = gScopes; cur; cur = cur->mNext) {
+        NS_ASSERTION(cur != this,
+                     "XPCWrappedNativeScope still in active list.");
+    }
+#endif
+
     if(mWrappedNativeMap)
     {
         NS_ASSERTION(0 == mWrappedNativeMap->Count(), "scope has non-empty map");
@@ -321,9 +312,6 @@ XPCWrappedNativeScope::~XPCWrappedNative
         NS_ASSERTION(0 == mWrapperMap->Count(), "scope has non-empty map");
         delete mWrapperMap;
     }
-
-    if(mContext)
-        mContext->RemoveScope(this);
 
     // XXX we should assert that we are dead or that xpconnect has shutdown
     // XXX might not want to do this at xpconnect shutdown time???
@@ -350,172 +338,38 @@ XPCWrappedNativeScope::GetPrototypeNoHel
     return mPrototypeNoHelper;
 }
 
+void
+XPCWrappedNativeScope::UnmapDyingNatives()
+{
+    mWrappedNativeMap->UnmapDyingNatives();
+    mWrappedNativeProtoMap->UnmapDyingNatives();
+    mWrapperMap->UnmapDyingNatives();
+}
+
 // static
 void
 XPCWrappedNativeScope::FinishedMarkPhaseOfGC(JSContext* cx, XPCJSRuntime* rt)
 {
-    // FIXME The lock may not be necessary since we are inside JSGC_MARK_END
-    // callback and GX serializes access to JS runtime. See bug 380139.
-    XPCAutoLock lock(rt->GetMapLock());
+    XPCWrappedNativeScope* prev = nsnull;
 
-    // We are in JSGC_MARK_END and JSGC_FINALIZE_END must always follow it
-    // calling FinishedFinalizationPhaseOfGC and clearing gDyingScopes in
-    // KillDyingScopes.
-    NS_ASSERTION(gDyingScopes == nsnull,
-                 "JSGC_MARK_END without JSGC_FINALIZE_END");
-
-    XPCWrappedNativeScope* prev = nsnull;
-    XPCWrappedNativeScope* cur = gScopes;
-
-    while(cur)
+    for(XPCWrappedNativeScope *cur = gScopes;
+        cur;
+        prev = cur, cur = cur->mNext)
     {
-        XPCWrappedNativeScope* next = cur->mNext;
-        if(cur->mGlobalJSObject &&
-           JS_IsAboutToBeFinalized(cx, cur->mGlobalJSObject))
+        if(NS_GetGC()->GetMark(cur))
         {
-            cur->mGlobalJSObject = nsnull;
-
-            // Move this scope from the live list to the dying list.
-            if(prev)
-                prev->mNext = next;
-            else
-                gScopes = next;
-            cur->mNext = gDyingScopes;
-            gDyingScopes = cur;
-            cur = nsnull;
+            // If the scope is marked, regulate its maps
+            cur->UnmapDyingNatives();
         }
         else
         {
-            if(cur->mPrototypeJSObject &&
-               JS_IsAboutToBeFinalized(cx, cur->mPrototypeJSObject))
-            {
-                cur->mPrototypeJSObject = nsnull;
-            }
-            if(cur->mPrototypeJSFunction &&
-               JS_IsAboutToBeFinalized(cx, cur->mPrototypeJSFunction))
-            {
-                cur->mPrototypeJSFunction = nsnull;
-            }
-            if(cur->mPrototypeNoHelper &&
-               JS_IsAboutToBeFinalized(cx, cur->mPrototypeNoHelper))
-            {
-                cur->mPrototypeNoHelper = nsnull;
-            }
+            // If the scope is not marked, remove it from our linked list
+            if(prev)
+                prev->mNext = cur->mNext;
+            else
+                gScopes = cur->mNext;
         }
-        if(cur)
-            prev = cur;
-        cur = next;
     }
-}
-
-// static
-void
-XPCWrappedNativeScope::FinishedFinalizationPhaseOfGC(JSContext* cx)
-{
-    XPCJSRuntime* rt = nsXPConnect::GetRuntime();
-    if(!rt)
-        return;
-
-    // FIXME The lock may not be necessary since we are inside
-    // JSGC_FINALIZE_END callback and at this point GC still serializes access
-    // to JS runtime. See bug 380139.
-    XPCAutoLock lock(rt->GetMapLock());
-    KillDyingScopes();
-}
-
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-WrappedNativeMarker(JSDHashTable *table, JSDHashEntryHdr *hdr,
-                    uint32 number, void *arg)
-{
-    ((Native2WrappedNativeMap::Entry*)hdr)->value->Mark();
-    return JS_DHASH_NEXT;
-}
-
-// We need to explicitly mark all the protos too because some protos may be
-// alive in the hashtable but not currently in use by any wrapper
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-WrappedNativeProtoMarker(JSDHashTable *table, JSDHashEntryHdr *hdr,
-                         uint32 number, void *arg)
-{
-    ((ClassInfo2WrappedNativeProtoMap::Entry*)hdr)->value->Mark();
-    return JS_DHASH_NEXT;
-}
-
-// static
-void
-XPCWrappedNativeScope::MarkAllWrappedNativesAndProtos()
-{
-    for(XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext)
-    {
-        cur->mWrappedNativeMap->Enumerate(WrappedNativeMarker, nsnull);
-        cur->mWrappedNativeProtoMap->Enumerate(WrappedNativeProtoMarker, nsnull);
-    }
-
-    DEBUG_TrackScopeTraversal();
-}
-
-#ifdef DEBUG
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-ASSERT_WrappedNativeSetNotMarked(JSDHashTable *table, JSDHashEntryHdr *hdr,
-                                 uint32 number, void *arg)
-{
-    ((Native2WrappedNativeMap::Entry*)hdr)->value->ASSERT_SetsNotMarked();
-    return JS_DHASH_NEXT;
-}
-
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-ASSERT_WrappedNativeProtoSetNotMarked(JSDHashTable *table, JSDHashEntryHdr *hdr,
-                                      uint32 number, void *arg)
-{
-    ((ClassInfo2WrappedNativeProtoMap::Entry*)hdr)->value->ASSERT_SetNotMarked();
-    return JS_DHASH_NEXT;
-}
-
-// static
-void
-XPCWrappedNativeScope::ASSERT_NoInterfaceSetsAreMarked()
-{
-    for(XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext)
-    {
-        cur->mWrappedNativeMap->Enumerate(
-            ASSERT_WrappedNativeSetNotMarked, nsnull);
-        cur->mWrappedNativeProtoMap->Enumerate(
-            ASSERT_WrappedNativeProtoSetNotMarked, nsnull);
-    }
-}
-#endif
-
-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
-WrappedNativeTearoffSweeper(JSDHashTable *table, JSDHashEntryHdr *hdr,
-                            uint32 number, void *arg)
-{
-    ((Native2WrappedNativeMap::Entry*)hdr)->value->SweepTearOffs();
-    return JS_DHASH_NEXT;
-}
-
-// static
-void
-XPCWrappedNativeScope::SweepAllWrappedNativeTearOffs()
-{
-    for(XPCWrappedNativeScope* cur = gScopes; cur; cur = cur->mNext)
-        cur->mWrappedNativeMap->Enumerate(WrappedNativeTearoffSweeper, nsnull);
-
-    DEBUG_TrackScopeTraversal();
-}
-
-// static
-void
-XPCWrappedNativeScope::KillDyingScopes()
-{
-    // always called inside the lock!
-    XPCWrappedNativeScope* cur = gDyingScopes;
-    while(cur)
-    {
-        XPCWrappedNativeScope* next = cur->mNext;
-        delete cur;
-        cur = next;
-    }
-    gDyingScopes = nsnull;
 }
 
 struct ShutdownData
@@ -564,28 +418,15 @@ XPCWrappedNativeScope::SystemIsBeingShut
     DEBUG_TrackScopeTraversal();
     DEBUG_TrackScopeShutdown();
 
-    int liveScopeCount = 0;
-
     ShutdownData data(cx);
 
-    XPCWrappedNativeScope* cur;
+    XPCWrappedNativeScope* cur = gScopes;
 
-    // First move all the scopes to the dying list.
-
-    cur = gScopes;
-    while(cur)
-    {
-        XPCWrappedNativeScope* next = cur->mNext;
-        cur->mNext = gDyingScopes;
-        gDyingScopes = cur;
-        cur = next;
-        liveScopeCount++;
-    }
     gScopes = nsnull;
 
-    // Walk the unified dying list and call shutdown on all wrappers and protos
+    // Walk the list of scopes and call shutdown on all wrappers and protos
 
-    for(cur = gDyingScopes; cur; cur = cur->mNext)
+    for(; cur; cur = cur->mNext)
     {
         // Give the Components object a chance to try to clean up.
         if(cur->mComponents)
@@ -599,9 +440,6 @@ XPCWrappedNativeScope::SystemIsBeingShut
                 Enumerate(WrappedNativeShutdownEnumerator,  &data);
     }
 
-    // Now it is safe to kill all the scopes.
-    KillDyingScopes();
-
 #ifdef XPC_DUMP_AT_SHUTDOWN
     if(data.wrapperCount)
         printf("deleting nsXPConnect  with %d live XPCWrappedNatives\n",
@@ -610,9 +448,6 @@ XPCWrappedNativeScope::SystemIsBeingShut
         printf("deleting nsXPConnect  with %d live XPCWrappedNativeProtos (%d shared)\n",
                data.sharedProtoCount + data.nonSharedProtoCount,
                data.sharedProtoCount);
-    if(liveScopeCount)
-        printf("deleting nsXPConnect  with %d live XPCWrappedNativeScopes\n",
-               liveScopeCount);
 #endif
 }
 
@@ -814,7 +649,6 @@ XPCWrappedNativeScope::DebugDumpAllScope
 
     XPC_LOG_ALWAYS(("chain of %d XPCWrappedNativeScope(s)", count));
     XPC_LOG_INDENT();
-        XPC_LOG_ALWAYS(("gDyingScopes @ %x", gDyingScopes));
         if(depth)
             for(cur = gScopes; cur; cur = cur->mNext)
                 cur->DebugDump(depth);
diff --git a/xpcom/glue/nsGenericFactory.h b/xpcom/glue/nsGenericFactory.h
--- a/xpcom/glue/nsGenericFactory.h
+++ b/xpcom/glue/nsGenericFactory.h
@@ -46,7 +46,7 @@
  * Most factories follow this simple pattern, so why not just use a function
  * pointer for most creation operations?
  */
-class nsGenericFactory : public nsIGenericFactory, public nsIClassInfo {
+class nsGenericFactory : public XPCOMGCFinalizedObject, public nsIGenericFactory, public nsIClassInfo {
 public:
     NS_DEFINE_STATIC_CID_ACCESSOR(NS_GENERICFACTORY_CID)
 
@@ -75,7 +75,7 @@ private:
 #include "nsIModule.h"
 #include "plhash.h"
 
-class nsGenericModule : public nsIModule
+class nsGenericModule : public XPCOMGCFinalizedObject, public nsIModule
 {
 public:
     nsGenericModule(const char* moduleName, 
@@ -92,14 +92,13 @@ public:
 
     NS_DECL_NSIMODULE
 
-    struct FactoryNode
+    struct FactoryNode : XPCOMGCObject
     {
         FactoryNode(nsIGenericFactory* fact, FactoryNode* next) 
         { 
             mFactory = fact; 
             mNext    = next;
         }
-        ~FactoryNode(){}
 
         nsCOMPtr<nsIGenericFactory> mFactory;
         FactoryNode* mNext;