Merge related patches together and reorder
authorbenjamin@smedbergs.us
Thu, 29 Nov 2007 10:58:32 -0500
changeset 57 230d3f80e0bb18f55c4df42e2baefcd98e436b3d
parent 56 e183e32bb7454727e344b24e968d87fe22398616
child 58 8ecbd849199dbe6e9e281aa564c617fd9eba4899
push id1
push userbsmedberg@mozilla.com
push dateTue, 15 Apr 2008 21:51:22 +0000
Merge related patches together and reorder
autorewrite-codehack.patch
comptr-rewrite.patch
comptr-rewrite.patch2
embedding-print64
gcobject-nodelete.patch
jscomponentloader-gc
jscomponentloader-gc2
jscomponentloader-gc3
layout-suck
layout-suck2
root-compmgr
root-compmgr2
series
xpcomproxy-gcalloc-patch2
xpcomproxy-gcalloc-patch3
xpcomproxy-gcalloc.patch
xpconnect-allocations
xpconnect-finalization
--- a/autorewrite-codehack.patch
+++ b/autorewrite-codehack.patch
@@ -1,13 +1,25 @@
+* * *
+
 diff --git a/embedding/browser/gtk/src/EmbedGlobalHistory.cpp b/embedding/browser/gtk/src/EmbedGlobalHistory.cpp
 --- a/embedding/browser/gtk/src/EmbedGlobalHistory.cpp
 +++ b/embedding/browser/gtk/src/EmbedGlobalHistory.cpp
-@@ -803,7 +803,8 @@ nsresult EmbedGlobalHistory::GetEntry(co
- 
-   nsresult rv = NS_OK;
-   SET_TITLE(newEntry, title);
--  rv |= SetLastVisitTime(newEntry, outValue);
-+  long long int iOutValue = outValue;
-+  rv |= SetLastVisitTime(newEntry, iOutValue);
-   rv |= SetIsWritten(newEntry);
-   rv |= SET_URL(newEntry, url);
-   BROKEN_RV_HANDLING_CODE(rv);
+@@ -762,7 +762,7 @@ nsresult EmbedGlobalHistory::GetEntry(co
+ {
+   char separator = (char) defaultSeparator;
+   int pos = 0;
+-  nsInt64 outValue = 0;
++  PRInt64 outValue = 0;
+   while (PR_TRUE) {
+     PRInt32 digit;
+     if (entry[pos] == separator) {
+@@ -772,8 +772,8 @@ nsresult EmbedGlobalHistory::GetEntry(co
+     if (entry[pos] == '\0' || !isdigit(entry[pos]))
+       return NS_ERROR_FAILURE;
+     digit = entry[pos] - '0';
+-    outValue *= nsInt64(10);
+-    outValue += nsInt64(digit);
++    outValue *= 10;
++    outValue += digit;
+     pos++;
+   }
+   char url[1024], title[1024];
--- a/comptr-rewrite.patch
+++ b/comptr-rewrite.patch
@@ -1,8 +1,10 @@
+* * *
+
 diff --git a/editor/libeditor/base/IMETextTxn.h b/editor/libeditor/base/IMETextTxn.h
 --- a/editor/libeditor/base/IMETextTxn.h
 +++ b/editor/libeditor/base/IMETextTxn.h
 @@ -120,9 +120,6 @@ protected:
    PRBool	mFixed;
  
    friend class TransactionFactory;
 -
@@ -1334,17 +1336,17 @@ diff --git a/xpcom/glue/nsCOMPtr.h b/xpc
 +
 +  New code should use MMgc::WriteBarrier<type> instead.
  */
  
 +#include "MMgc.h"
  
    // Wrapping includes can speed up compiles (see "Large Scale C++ Software Design")
  #ifndef nsDebug_h___
-@@ -65,1610 +60,456 @@
+@@ -65,1609 +60,455 @@
    // for |nsresult|, |NS_ADDREF|, |NS_GET_TEMPLATE_IID| et al
  #endif
  
 -#ifndef nscore_h___
 -#include "nscore.h"
 -  // for |NS_COM_GLUE|
 -#endif
 -
@@ -3380,18 +3382,17 @@ diff --git a/xpcom/glue/nsCOMPtr.h b/xpc
 +  {
 +    return mRawPtr;
 +  }
 +
 +private:
 +  T *mRawPtr;
 +};
  
- 
- 
+ #endif // !defined(nsCOMPtr_h___)
 diff --git a/xpcom/glue/nsComponentManagerUtils.cpp b/xpcom/glue/nsComponentManagerUtils.cpp
 --- a/xpcom/glue/nsComponentManagerUtils.cpp
 +++ b/xpcom/glue/nsComponentManagerUtils.cpp
 @@ -193,103 +193,62 @@ CallGetClassObject(const char *aContract
  
  #endif
  
 -nsresult
@@ -3822,17 +3823,17 @@ diff --git a/xpcom/glue/nsServiceManager
 --- a/xpcom/glue/nsServiceManagerUtils.h
 +++ b/xpcom/glue/nsServiceManagerUtils.h
 @@ -1,4 +1,4 @@
 -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  /* ***** BEGIN LICENSE BLOCK *****
   * Version: MPL 1.1/GPL 2.0/LGPL 2.1
   *
-@@ -41,6 +41,136 @@
+@@ -41,6 +41,138 @@
  #include "nsIServiceManager.h"
  #include "nsCOMPtr.h"
  
 +NS_COM_GLUE nsresult
 +CallGetService(const nsCID &aClass, const nsIID &aIID, void **aResult);
 +
 +NS_COM_GLUE nsresult
 +CallGetService(const char *aContractID, const nsIID &aIID, void **aResult);
@@ -3945,31 +3946,33 @@ diff --git a/xpcom/glue/nsServiceManager
 +  {
 +    return static_cast<D*>(get(NS_GET_TEMPLATE_IID(D)));
 +  }
 +    
 +private:
 +  void* NS_FASTCALL get(const nsIID &aIID) const
 +  {
 +    void *result = NULL;
-+    *mErrorPtr = CallGetService(mContractID, aIID, &result);
-+    if (NS_FAILED(*mErrorPtr))
++    nsresult rv = CallGetService(mContractID, aIID, &result);
++    if (mErrorPtr)
++      *mErrorPtr = rv;
++    if (NS_FAILED(rv))
 +      return NULL;
 +
 +    return result;
 +  }
 +
 +  const char*                 mContractID;
 +  nsresult*                   mErrorPtr;
 +};
 +
  inline
  const nsGetServiceByCID
  do_GetService(const nsCID& aCID)
-@@ -69,23 +199,32 @@ do_GetService( const char* aContractID, 
+@@ -69,23 +201,32 @@ do_GetService( const char* aContractID, 
      return nsGetServiceByContractIDWithError(aContractID, error);
  }
  
 -class nsGetServiceFromCategory : public nsCOMPtr_helper
 -{
 - public:
 -    nsGetServiceFromCategory(const char* aCategory, const char* aEntry,
 -                             nsresult* aErrorPtr)
@@ -4009,17 +4012,17 @@ diff --git a/xpcom/glue/nsServiceManager
 +  void* get(const nsIID &aIID) const;
 +
 +  const char*                 mCategory;
 +  const char*                 mEntry;
 +  nsresult*                   mErrorPtr;
  };
  
  inline
-@@ -96,11 +235,7 @@ do_GetServiceFromCategory( const char* c
+@@ -96,11 +237,7 @@ do_GetServiceFromCategory( const char* c
      return nsGetServiceFromCategory(category, entry, error);
  }
  
 -NS_COM_GLUE nsresult
 -CallGetService(const nsCID &aClass, const nsIID &aIID, void **aResult);
 -
 -NS_COM_GLUE nsresult
 -CallGetService(const char *aContractID, const nsIID &aIID, void **aResult);
deleted file mode 100644
--- a/comptr-rewrite.patch2
+++ /dev/null
@@ -1,16 +0,0 @@
-diff --git a/xpcom/glue/nsServiceManagerUtils.h b/xpcom/glue/nsServiceManagerUtils.h
---- a/xpcom/glue/nsServiceManagerUtils.h
-+++ b/xpcom/glue/nsServiceManagerUtils.h
-@@ -164,8 +164,10 @@ private:
-   void* NS_FASTCALL get(const nsIID &aIID) const
-   {
-     void *result = NULL;
--    *mErrorPtr = CallGetService(mContractID, aIID, &result);
--    if (NS_FAILED(*mErrorPtr))
-+    nsresult rv = CallGetService(mContractID, aIID, &result);
-+    if (mErrorPtr)
-+      *mErrorPtr = rv;
-+    if (NS_FAILED(rv))
-       return NULL;
- 
-     return result;
deleted file mode 100644
--- a/embedding-print64
+++ /dev/null
@@ -1,33 +0,0 @@
-diff --git a/embedding/browser/gtk/src/EmbedGlobalHistory.cpp b/embedding/browser/gtk/src/EmbedGlobalHistory.cpp
---- a/embedding/browser/gtk/src/EmbedGlobalHistory.cpp
-+++ b/embedding/browser/gtk/src/EmbedGlobalHistory.cpp
-@@ -759,7 +759,7 @@ nsresult EmbedGlobalHistory::GetEntry(co
- {
-   char separator = (char) defaultSeparator;
-   int pos = 0;
--  nsInt64 outValue = 0;
-+  PRInt64 outValue = 0;
-   while (PR_TRUE) {
-     PRInt32 digit;
-     if (entry[pos] == separator) {
-@@ -769,8 +769,8 @@ nsresult EmbedGlobalHistory::GetEntry(co
-     if (entry[pos] == '\0' || !isdigit(entry[pos]))
-       return NS_ERROR_FAILURE;
-     digit = entry[pos] - '0';
--    outValue *= nsInt64(10);
--    outValue += nsInt64(digit);
-+    outValue *= 10;
-+    outValue += digit;
-     pos++;
-   }
-   char url[1024], title[1024];
-@@ -800,8 +800,7 @@ nsresult EmbedGlobalHistory::GetEntry(co
- 
-   nsresult rv = NS_OK;
-   SET_TITLE(newEntry, title);
--  long long int iOutValue = outValue;
--  rv |= SetLastVisitTime(newEntry, iOutValue);
-+  rv |= SetLastVisitTime(newEntry, outValue);
-   rv |= SetIsWritten(newEntry);
-   rv |= SET_URL(newEntry, url);
-   BROKEN_RV_HANDLING_CODE(rv);
--- a/gcobject-nodelete.patch
+++ b/gcobject-nodelete.patch
@@ -111,62 +111,37 @@ diff --git a/js/src/xpconnect/loader/moz
              return NS_ERROR_OUT_OF_MEMORY;
 -        newEntry.forget();
      }
      
      return NS_OK;
 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
-@@ -212,16 +212,6 @@ JSClassSweeper(JSDHashTable *table, JSDH
+@@ -161,16 +161,6 @@ JSClassSweeper(JSDHashTable *table, JSDH
+     return JS_DHASH_REMOVE;
  }
  
- JS_STATIC_DLL_CALLBACK(JSDHashOperator)
+-JS_STATIC_DLL_CALLBACK(JSDHashOperator)
 -DyingProtoKiller(JSDHashTable *table, JSDHashEntryHdr *hdr,
 -                 uint32 number, void *arg)
 -{
 -    XPCWrappedNativeProto* proto =
 -        (XPCWrappedNativeProto*)((JSDHashEntryStub*)hdr)->key;
 -    delete proto;
 -    return JS_DHASH_REMOVE;
 -}
 -
--JS_STATIC_DLL_CALLBACK(JSDHashOperator)
- DetachedWrappedNativeProtoMarker(JSDHashTable *table, JSDHashEntryHdr *hdr,
-                                  uint32 number, void *arg)
- {
-@@ -556,8 +546,10 @@ JSBool XPCJSRuntime::GCCallback(JSContex
-                 // referencing the protos in the dying list are themselves dead.
-                 // So, we can safely delete all the protos in the list.
- 
-+#if 0 // removed by bsmedberg for XPCOMGC
-                 self->mDyingWrappedNativeProtoMap->
-                     Enumerate(DyingProtoKiller, nsnull);
-+#endif
- 
- 
-                 // mThreadRunningGC indicates that GC is running.
+ // GCCallback calls are chained
+ JS_STATIC_DLL_CALLBACK(JSBool)
+ ContextCallback(JSContext *cx, uintN operation)
 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
-@@ -570,13 +570,6 @@ XPCWrappedNative::~XPCWrappedNative()
-     DEBUG_TrackDeleteWrapper(this);
- 
-     XPCWrappedNativeProto* proto = GetProto();
--
--    if(mScriptableInfo &&
--       (!HasProto() ||
--        (proto && proto->GetScriptableInfo() != mScriptableInfo)))
--    {
--        delete mScriptableInfo;
--    }
- 
-     Native2WrappedNativeMap* map = GetScope()->GetWrappedNativeMap();
-     {   // scoped lock
-@@ -1000,13 +993,6 @@ XPCWrappedNative::SystemIsBeingShutDown(
+@@ -938,13 +938,6 @@ XPCWrappedNative::SystemIsBeingShutDown(
      if(HasProto())
          proto->SystemIsBeingShutDown(cx);
  
 -    if(mScriptableInfo &&
 -       (!HasProto() ||
 -        (proto && proto->GetScriptableInfo() != mScriptableInfo)))
 -    {
 -        delete mScriptableInfo;
--- a/jscomponentloader-gc
+++ b/jscomponentloader-gc
@@ -1,8 +1,11 @@
+* * *
+* * *
+
 diff --git a/js/src/xpconnect/loader/mozJSComponentLoader.cpp b/js/src/xpconnect/loader/mozJSComponentLoader.cpp
 --- a/js/src/xpconnect/loader/mozJSComponentLoader.cpp
 +++ b/js/src/xpconnect/loader/mozJSComponentLoader.cpp
 @@ -595,7 +595,7 @@ mozJSComponentLoader::LoadModule(nsILoca
      if (!entry)
          return NS_ERROR_OUT_OF_MEMORY;
  
 -    rv = GlobalForLocation(aComponentFile, &entry->global, &entry->location);
@@ -74,27 +77,36 @@ diff --git a/js/src/xpconnect/loader/moz
 -                               &newEntry->location);
 +        rv = GlobalForLocation(componentFile, &newEntry->global);
  
          mInProgressImports.Remove(lfhash);
  
 diff --git a/js/src/xpconnect/loader/mozJSComponentLoader.h b/js/src/xpconnect/loader/mozJSComponentLoader.h
 --- a/js/src/xpconnect/loader/mozJSComponentLoader.h
 +++ b/js/src/xpconnect/loader/mozJSComponentLoader.h
+@@ -53,7 +53,7 @@
+ #include "nsITimer.h"
+ #include "nsIObserver.h"
+ #include "xpcIJSModuleLoader.h"
+-#include "nsClassHashtable.h"
++#include "nsInterfaceHashtable.h"
+ #include "nsDataHashtable.h"
+ #ifndef XPCONNECT_STANDALONE
+ #include "nsIPrincipal.h"
 @@ -109,8 +109,7 @@ class mozJSComponentLoader : public XPCO
      void UnloadModules();
  
      nsresult GlobalForLocation(nsILocalFile *aComponent,
 -                               JSObject **aGlobal,
 -                               char **location);
 +                               JSObject **aGlobal);
  
      nsresult StartFastLoad(nsIFastLoadService *flSvc);
      nsresult ReadScript(nsIFastLoadService *flSvc, const char *nativePath,
-@@ -136,30 +135,15 @@ class mozJSComponentLoader : public XPCO
+@@ -136,37 +135,22 @@ class mozJSComponentLoader : public XPCO
      JSRuntime *mRuntime;
      JSContext *mContext;
  
 -    class ModuleEntry
 +    class ModuleEntry : public XPCOMGCObject
      {
      public:
          ModuleEntry() {
@@ -116,8 +128,18 @@ diff --git a/js/src/xpconnect/loader/moz
          }
  
          nsCOMPtr<nsIModule>  module;
          JSObject            *global;
 -        char                *location;
      };
  
      friend class ModuleEntry;
+ 
+-    nsClassHashtable<nsHashableHashKey, ModuleEntry> mModules;
+-    nsClassHashtable<nsHashableHashKey, ModuleEntry> mImports;
+-    nsDataHashtable<nsHashableHashKey, ModuleEntry*> mInProgressImports;
++    nsInterfaceHashtable<nsHashableHashKey, ModuleEntry, GCAllocator> mModules;
++    nsInterfaceHashtable<nsHashableHashKey, ModuleEntry, GCAllocator> mImports;
++    nsDataHashtable<nsHashableHashKey, ModuleEntry*, GCAllocator> mInProgressImports;
+ 
+     PRBool mInitialized;
+ };
deleted file mode 100644
--- a/jscomponentloader-gc2
+++ /dev/null
@@ -1,16 +0,0 @@
-diff --git a/js/src/xpconnect/loader/mozJSComponentLoader.h b/js/src/xpconnect/loader/mozJSComponentLoader.h
---- a/js/src/xpconnect/loader/mozJSComponentLoader.h
-+++ b/js/src/xpconnect/loader/mozJSComponentLoader.h
-@@ -148,9 +148,9 @@ class mozJSComponentLoader : public XPCO
- 
-     friend class ModuleEntry;
- 
--    nsClassHashtable<nsHashableHashKey, ModuleEntry> mModules;
--    nsClassHashtable<nsHashableHashKey, ModuleEntry> mImports;
--    nsDataHashtable<nsHashableHashKey, ModuleEntry*> mInProgressImports;
-+    nsClassHashtable<nsHashableHashKey, ModuleEntry, GCAllocator> mModules;
-+    nsClassHashtable<nsHashableHashKey, ModuleEntry, GCAllocator> mImports;
-+    nsDataHashtable<nsHashableHashKey, ModuleEntry*, GCAllocator> mInProgressImports;
- 
-     PRBool mInitialized;
- };
deleted file mode 100644
--- a/jscomponentloader-gc3
+++ /dev/null
@@ -1,23 +0,0 @@
-diff --git a/js/src/xpconnect/loader/mozJSComponentLoader.h b/js/src/xpconnect/loader/mozJSComponentLoader.h
---- a/js/src/xpconnect/loader/mozJSComponentLoader.h
-+++ b/js/src/xpconnect/loader/mozJSComponentLoader.h
-@@ -53,7 +53,7 @@
- #include "nsITimer.h"
- #include "nsIObserver.h"
- #include "xpcIJSModuleLoader.h"
--#include "nsClassHashtable.h"
-+#include "nsInterfaceHashtable.h"
- #include "nsDataHashtable.h"
- #ifndef XPCONNECT_STANDALONE
- #include "nsIPrincipal.h"
-@@ -148,8 +148,8 @@ class mozJSComponentLoader : public XPCO
- 
-     friend class ModuleEntry;
- 
--    nsClassHashtable<nsHashableHashKey, ModuleEntry, GCAllocator> mModules;
--    nsClassHashtable<nsHashableHashKey, ModuleEntry, GCAllocator> mImports;
-+    nsInterfaceHashtable<nsHashableHashKey, ModuleEntry, GCAllocator> mModules;
-+    nsInterfaceHashtable<nsHashableHashKey, ModuleEntry, GCAllocator> mImports;
-     nsDataHashtable<nsHashableHashKey, ModuleEntry*, GCAllocator> mInProgressImports;
- 
-     PRBool mInitialized;
--- a/layout-suck
+++ b/layout-suck
@@ -1,12 +1,64 @@
+* * *
+
 diff --git a/layout/mathml/base/src/nsMathMLChar.cpp b/layout/mathml/base/src/nsMathMLChar.cpp
 --- a/layout/mathml/base/src/nsMathMLChar.cpp
 +++ b/layout/mathml/base/src/nsMathMLChar.cpp
 @@ -132,7 +132,7 @@ enum {eExtension_base, eExtension_varian
  #define NS_TABLE_STATE_READY        1
  
  // Hook to resolve common assignments to the PUA
 -static nsCOMPtr<nsIPersistentProperties> gPUAProperties; 
 +static nsIPersistentProperties* gPUAProperties; 
  
  // helper to check if a font is installed
  static PRBool
+@@ -195,14 +195,14 @@ Clean(nsString& aValue)
+ // helper to load a MathFont Property File
+ static nsresult
+ LoadProperties(const nsString& aName,
+-               nsCOMPtr<nsIPersistentProperties>& aProperties)
++               nsIPersistentProperties** aProperties)
+ {
+   nsAutoString uriStr;
+   uriStr.AssignLiteral("resource://gre/res/fonts/mathfont");
+   uriStr.Append(aName);
+   uriStr.StripWhitespace(); // that may come from aName
+   uriStr.AppendLiteral(".properties");
+-  return NS_LoadPersistentPropertiesFromURISpec(getter_AddRefs(aProperties), 
++  return NS_LoadPersistentPropertiesFromURISpec(aProperties, 
+                                                 NS_ConvertUTF16toUTF8(uriStr));
+ }
+ 
+@@ -359,7 +359,7 @@ nsGlyphTable::ElementAt(nsPresContext* a
+       mState = NS_TABLE_STATE_ERROR;
+       return kNullGlyph;
+     }
+-    nsresult rv = LoadProperties(*mFontName[0], mGlyphProperties);
++    nsresult rv = LoadProperties(*mFontName[0], getter_AddRefs(mGlyphProperties));
+ #ifdef NS_DEBUG
+     nsCAutoString uriStr;
+     uriStr.AssignLiteral("resource://gre/res/fonts/mathfont");
+@@ -1221,7 +1221,7 @@ InitGlobals(nsPresContext* aPresContext)
+ 
+   nsCAutoString key;
+   nsAutoString value;
+-  nsCOMPtr<nsIPersistentProperties> mathfontProp;
++  nsIPersistentProperties* mathfontProp = nsnull;
+   nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
+ 
+   // Add the math fonts in the gGlyphTableList in order of preference ...
+@@ -1230,12 +1230,12 @@ InitGlobals(nsPresContext* aPresContext)
+ 
+   // Load the "mathfont.properties" file
+   value.Truncate();
+-  rv = LoadProperties(value, mathfontProp);
++  rv = LoadProperties(value, &mathfontProp);
+   if (NS_FAILED(rv)) return rv;
+ 
+   // Load the "mathfontPUA.properties" file
+   value.AssignLiteral("PUA");
+-  rv = LoadProperties(value, gPUAProperties);
++  rv = LoadProperties(value, &gPUAProperties);
+   if (NS_FAILED(rv)) return rv;
+ 
+   // Get the default list of mathfonts to be used for stretchy characters
deleted file mode 100644
--- a/layout-suck2
+++ /dev/null
@@ -1,53 +0,0 @@
-diff --git a/layout/mathml/base/src/nsMathMLChar.cpp b/layout/mathml/base/src/nsMathMLChar.cpp
---- a/layout/mathml/base/src/nsMathMLChar.cpp
-+++ b/layout/mathml/base/src/nsMathMLChar.cpp
-@@ -195,14 +195,14 @@ Clean(nsString& aValue)
- // helper to load a MathFont Property File
- static nsresult
- LoadProperties(const nsString& aName,
--               nsCOMPtr<nsIPersistentProperties>& aProperties)
-+               nsIPersistentProperties** aProperties)
- {
-   nsAutoString uriStr;
-   uriStr.AssignLiteral("resource://gre/res/fonts/mathfont");
-   uriStr.Append(aName);
-   uriStr.StripWhitespace(); // that may come from aName
-   uriStr.AppendLiteral(".properties");
--  return NS_LoadPersistentPropertiesFromURISpec(getter_AddRefs(aProperties), 
-+  return NS_LoadPersistentPropertiesFromURISpec(aProperties, 
-                                                 NS_ConvertUTF16toUTF8(uriStr));
- }
- 
-@@ -359,7 +359,7 @@ nsGlyphTable::ElementAt(nsPresContext* a
-       mState = NS_TABLE_STATE_ERROR;
-       return kNullGlyph;
-     }
--    nsresult rv = LoadProperties(*mFontName[0], mGlyphProperties);
-+    nsresult rv = LoadProperties(*mFontName[0], getter_AddRefs(mGlyphProperties));
- #ifdef NS_DEBUG
-     nsCAutoString uriStr;
-     uriStr.AssignLiteral("resource://gre/res/fonts/mathfont");
-@@ -1221,7 +1221,7 @@ InitGlobals(nsPresContext* aPresContext)
- 
-   nsCAutoString key;
-   nsAutoString value;
--  nsCOMPtr<nsIPersistentProperties> mathfontProp;
-+  nsIPersistentProperties* mathfontProp = nsnull;
-   nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
- 
-   // Add the math fonts in the gGlyphTableList in order of preference ...
-@@ -1230,12 +1230,12 @@ InitGlobals(nsPresContext* aPresContext)
- 
-   // Load the "mathfont.properties" file
-   value.Truncate();
--  rv = LoadProperties(value, mathfontProp);
-+  rv = LoadProperties(value, &mathfontProp);
-   if (NS_FAILED(rv)) return rv;
- 
-   // Load the "mathfontPUA.properties" file
-   value.AssignLiteral("PUA");
--  rv = LoadProperties(value, gPUAProperties);
-+  rv = LoadProperties(value, &gPUAProperties);
-   if (NS_FAILED(rv)) return rv;
- 
-   // Get the default list of mathfonts to be used for stretchy characters
--- a/root-compmgr
+++ b/root-compmgr
@@ -1,8 +1,10 @@
+* * *
+
 diff --git a/xpcom/build/nsXPComInit.cpp b/xpcom/build/nsXPComInit.cpp
 --- a/xpcom/build/nsXPComInit.cpp
 +++ b/xpcom/build/nsXPComInit.cpp
 @@ -329,7 +329,7 @@ static PRBool CheckUpdateFile()
  }
  
  
 -nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL;
@@ -74,53 +76,118 @@ diff --git a/xpcom/components/nsComponen
      nsICategoryManager* catman = nsnull;
      void *result = NULL;
 -    nsComponentManagerImpl *compMgr = nsComponentManagerImpl::gComponentManager;
 +    nsComponentManagerImpl *compMgr =
 +        nsComponentManagerImpl::gComponentManager->instance;
      if (!compMgr) {
          rv = NS_ERROR_NOT_INITIALIZED;
          goto error;
-@@ -1259,7 +1260,7 @@ AutoRegEntryWriter(nsIHashable *aKey, PR
+@@ -1008,13 +1009,6 @@ nsComponentManagerImpl::ReadPersistentRe
+         if (loadertype == NS_LOADER_TYPE_INVALID) {
+             NS_ERROR("Could not create LoaderType");
+             continue;
+-        }
+-
+-        void *mem;
+-        PL_ARENA_ALLOCATE(mem, &mArena, sizeof(nsFactoryEntry));
+-        if (!mem) {
+-            rv = NS_ERROR_OUT_OF_MEMORY;
+-            goto out;
+         }
+ 
+         nsFactoryEntry *entry =
+@@ -1259,7 +1253,7 @@ AutoRegEntryWriter(nsIHashable *aKey, PR
      nsILocalFile* lf(do_QueryInterface(aKey));
  
      nsCAutoString location;
 -    nsComponentManagerImpl::gComponentManager->
 +    nsComponentManagerImpl::gComponentManager->instance->
          RegistryLocationForFile(lf, location);
  
      PR_fprintf(fd, "%s,%lld\n", location.get(), (PRInt64) aTimestamp);
-@@ -3234,7 +3235,7 @@ RegisterStaticModule(const char *key, ns
+@@ -1965,10 +1959,6 @@ nsComponentManagerImpl::RegisterService(
+     nsFactoryEntry *entry = GetFactoryEntry(aClass);
+ 
+     if (!entry) {
+-        void *mem;
+-        PL_ARENA_ALLOCATE(mem, &mArena, sizeof(nsFactoryEntry));
+-        if (!mem)
+-            return NS_ERROR_OUT_OF_MEMORY;
+         entry = new nsFactoryEntry(aClass, (nsIFactory*) nsnull);
+ 
+         nsFactoryTableEntry* factoryTableEntry =
+@@ -2026,10 +2016,6 @@ nsComponentManagerImpl::RegisterService(
+     nsFactoryEntry *entry = GetFactoryEntry(aContractID, contractIDLen);
+ 
+     if (!entry) {
+-        void *mem;
+-        PL_ARENA_ALLOCATE(mem, &mArena, sizeof(nsFactoryEntry));
+-        if (!mem)
+-            return NS_ERROR_OUT_OF_MEMORY;
+         entry = new nsFactoryEntry(kEmptyCID, (nsIFactory*) nsnull);
+ 
+         nsContractIDTableEntry* contractIDTableEntry =
+@@ -2478,11 +2464,6 @@ nsComponentManagerImpl::RegisterFactory(
+         return NS_ERROR_FACTORY_EXISTS;
+     }
+ 
+-    void *mem;
+-    PL_ARENA_ALLOCATE(mem, &mArena, sizeof(nsFactoryEntry));
+-    if (!mem)
+-        return NS_ERROR_OUT_OF_MEMORY;
+-
+     entry = new nsFactoryEntry(aClass, aFactory, entry);
+ 
+     factoryTableEntry->mFactoryEntry = entry;
+@@ -2636,13 +2617,6 @@ nsComponentManagerImpl::RegisterComponen
+         entry->ReInit(typeIndex, aRegistryName);
+     }
+     else {
+-
+-        // Arena allocate the nsFactoryEntry
+-        void *mem;
+-        PL_ARENA_ALLOCATE(mem, &mArena, sizeof(nsFactoryEntry));
+-        if (!mem)
+-            return NS_ERROR_OUT_OF_MEMORY;
+-
+         mRegistryDirty = PR_TRUE;
+         entry = new nsFactoryEntry(aClass,
+                                    typeIndex,
+@@ -3234,7 +3208,7 @@ RegisterStaticModule(const char *key, ns
                       nsTArray<DeferredModule, GCAllocator> &deferred)
  {
      nsresult rv = module->
 -        RegisterSelf(nsComponentManagerImpl::gComponentManager,
 +        RegisterSelf(nsComponentManagerImpl::gComponentManager->instance,
                       nsnull, key, staticComponentType);
  
      if (NS_ERROR_FACTORY_REGISTER_AGAIN == rv) {
-@@ -3527,7 +3528,7 @@ nsFactoryEntry::nsFactoryEntry(const nsC
+@@ -3527,9 +3501,10 @@ nsFactoryEntry::nsFactoryEntry(const nsC
      mLoaderType(aLoaderType),
      mLocationKey(
        ArenaStrdup(aLocationKey,
 -                  &nsComponentManagerImpl::gComponentManager->mArena)),
 +                  &nsComponentManagerImpl::gComponentManager->instance->mArena)),
      mParent(aParent)
  {
++    ASSERT_GCObject(this);
  }
-@@ -3541,7 +3542,7 @@ nsFactoryEntry::ReInit(LoaderType  aLoad
+ 
+ void
+@@ -3541,7 +3516,7 @@ nsFactoryEntry::ReInit(LoaderType  aLoad
      if (!mLocationKey || strcmp(mLocationKey, aLocationKey)) {
          mLocationKey =
              ArenaStrdup(aLocationKey,
 -                        &nsComponentManagerImpl::gComponentManager->mArena);
 +                        &nsComponentManagerImpl::gComponentManager->instance->mArena);
      }
  }
  
-@@ -3557,20 +3558,20 @@ nsFactoryEntry::GetFactory(nsIFactory **
+@@ -3557,20 +3532,20 @@ nsFactoryEntry::GetFactory(nsIFactory **
          nsIModule* module = nsnull;
  
          if (mLoaderType == NS_LOADER_TYPE_STATIC) {
 -            rv = nsComponentManagerImpl::gComponentManager->
 +            rv = nsComponentManagerImpl::gComponentManager->instance->
                  mStaticModuleLoader.
                  GetModuleFor(mLocationKey,
                               &module);
@@ -134,26 +201,39 @@ diff --git a/xpcom/components/nsComponen
              NS_ENSURE_SUCCESS(rv, rv);
  
              nsIModuleLoader* loader =
 -                nsComponentManagerImpl::gComponentManager->
 +                nsComponentManagerImpl::gComponentManager->instance->
                      LoaderForType(mLoaderType);
              if (!loader)
                  return NS_ERROR_FAILURE;
-@@ -3588,7 +3589,7 @@ nsFactoryEntry::GetFactory(nsIFactory **
+@@ -3588,7 +3563,7 @@ nsFactoryEntry::GetFactory(nsIFactory **
          }
  
          rv = module->
 -            GetClassObject(nsComponentManagerImpl::gComponentManager,
 +            GetClassObject(nsComponentManagerImpl::gComponentManager->instance,
                             mCid,
                             NS_GET_IID(nsIFactory),
                             getter_AddRefs(mFactory));
-@@ -3620,35 +3621,24 @@ NS_COM nsresult
+@@ -3606,11 +3581,7 @@ nsFactoryEntry::GetFactory(nsIFactory **
+ 
+ nsFactoryEntry::~nsFactoryEntry()
+ {
+-    // nsFactoryEntry is arena-allocated. So we don't delete it;
+-    // call the destructor by hand.
+-
+-    if (mParent)
+-        mParent->~nsFactoryEntry();
++    NS_NOTREACHED("Not finalized!");
+ }
+ 
+ ////////////////////////////////////////////////////////////////////////////////
+@@ -3620,35 +3591,24 @@ NS_COM nsresult
  NS_COM nsresult
  NS_GetComponentManager(nsIComponentManager* *result)
  {
 -    if (nsComponentManagerImpl::gComponentManager == nsnull)
 -    {
 -        // XPCOM needs initialization.
 -        nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull);
 -        if (NS_FAILED(rv))
@@ -191,17 +271,17 @@ diff --git a/xpcom/components/nsComponen
 +        NS_ERROR("XPCOM was not initalized.");
 +        return NS_ERROR_NOT_INITIALIZED;
 +    }
 +
 +    *result = nsComponentManagerImpl::gComponentManager->instance;
      return NS_OK;
  }
  
-@@ -3656,18 +3646,10 @@ NS_COM nsresult
+@@ -3656,18 +3616,10 @@ NS_COM nsresult
  NS_COM nsresult
  NS_GetComponentRegistrar(nsIComponentRegistrar* *result)
  {
 -    nsresult rv = NS_OK;
 -
 -    if (nsComponentManagerImpl::gComponentManager == nsnull)
 -    {
 -        // XPCOM needs initialization.
deleted file mode 100644
--- a/root-compmgr2
+++ /dev/null
@@ -1,86 +0,0 @@
-diff --git a/xpcom/components/nsComponentManager.cpp b/xpcom/components/nsComponentManager.cpp
---- a/xpcom/components/nsComponentManager.cpp
-+++ b/xpcom/components/nsComponentManager.cpp
-@@ -1011,13 +1011,6 @@ nsComponentManagerImpl::ReadPersistentRe
-             continue;
-         }
- 
--        void *mem;
--        PL_ARENA_ALLOCATE(mem, &mArena, sizeof(nsFactoryEntry));
--        if (!mem) {
--            rv = NS_ERROR_OUT_OF_MEMORY;
--            goto out;
--        }
--
-         nsFactoryEntry *entry =
-             new nsFactoryEntry(aClass, loadertype, values[4]);
- 
-@@ -1966,10 +1959,6 @@ nsComponentManagerImpl::RegisterService(
-     nsFactoryEntry *entry = GetFactoryEntry(aClass);
- 
-     if (!entry) {
--        void *mem;
--        PL_ARENA_ALLOCATE(mem, &mArena, sizeof(nsFactoryEntry));
--        if (!mem)
--            return NS_ERROR_OUT_OF_MEMORY;
-         entry = new nsFactoryEntry(aClass, (nsIFactory*) nsnull);
- 
-         nsFactoryTableEntry* factoryTableEntry =
-@@ -2027,10 +2016,6 @@ nsComponentManagerImpl::RegisterService(
-     nsFactoryEntry *entry = GetFactoryEntry(aContractID, contractIDLen);
- 
-     if (!entry) {
--        void *mem;
--        PL_ARENA_ALLOCATE(mem, &mArena, sizeof(nsFactoryEntry));
--        if (!mem)
--            return NS_ERROR_OUT_OF_MEMORY;
-         entry = new nsFactoryEntry(kEmptyCID, (nsIFactory*) nsnull);
- 
-         nsContractIDTableEntry* contractIDTableEntry =
-@@ -2479,11 +2464,6 @@ nsComponentManagerImpl::RegisterFactory(
-         return NS_ERROR_FACTORY_EXISTS;
-     }
- 
--    void *mem;
--    PL_ARENA_ALLOCATE(mem, &mArena, sizeof(nsFactoryEntry));
--    if (!mem)
--        return NS_ERROR_OUT_OF_MEMORY;
--
-     entry = new nsFactoryEntry(aClass, aFactory, entry);
- 
-     factoryTableEntry->mFactoryEntry = entry;
-@@ -2637,13 +2617,6 @@ nsComponentManagerImpl::RegisterComponen
-         entry->ReInit(typeIndex, aRegistryName);
-     }
-     else {
--
--        // Arena allocate the nsFactoryEntry
--        void *mem;
--        PL_ARENA_ALLOCATE(mem, &mArena, sizeof(nsFactoryEntry));
--        if (!mem)
--            return NS_ERROR_OUT_OF_MEMORY;
--
-         mRegistryDirty = PR_TRUE;
-         entry = new nsFactoryEntry(aClass,
-                                    typeIndex,
-@@ -3531,6 +3504,7 @@ nsFactoryEntry::nsFactoryEntry(const nsC
-                   &nsComponentManagerImpl::gComponentManager->instance->mArena)),
-     mParent(aParent)
- {
-+    ASSERT_GCObject(this);
- }
- 
- void
-@@ -3607,11 +3581,7 @@ nsFactoryEntry::GetFactory(nsIFactory **
- 
- nsFactoryEntry::~nsFactoryEntry()
- {
--    // nsFactoryEntry is arena-allocated. So we don't delete it;
--    // call the destructor by hand.
--
--    if (mParent)
--        mParent->~nsFactoryEntry();
-+    NS_NOTREACHED("Not finalized!");
- }
- 
- ////////////////////////////////////////////////////////////////////////////////
--- a/series
+++ b/series
@@ -1,13 +1,15 @@
-sqlite-is-c.patch
-activex-oji.patch
+64bit
+configure-with-threadsafe-mmgc
+sqlite-is-c.patch # bug 400839
+activex-oji.patch # bug 398152
 success-macros.patch
-autorewrite-codehack.patch
-consoleservice.patch
+autorewrite-codehack.patch # bug 405996
+consoleservice.patch # bug 397929
 no-standaloneglue.patch
 comptr-rewrite.patch
 prerewrite_fixes.patch
 maybeweak-crap.patch
 remove-cyclec.patch
 cc-semicolons.patch
 xpcomgcbase.patch
 necko-cookie.patch
@@ -21,48 +23,37 @@ proxy-fixup.patch
 windows-warning.patch
 comarray.patch
 gc-hashtables.patch
 xpti-workingset.patch
 unbraced-if-fixes.patch
 more-gcobjects.patch
 fix-garburator.patch
 xpcomproxy-gcalloc.patch
-automatic-remove-addrefs.patch
-automatic-gcobject.patch
+# automatic-remove-addrefs.patch
+# automatic-gcobject.patch
 hashentry-fixups.patch
 uconverter-suck
 xpinstall-suck
 layout-suck
 widget-suck
 TArray-allocator
 compmgr-loadertype
 TArray-extra
 xpconnect-allocations
 observerlist-gc
 jscomponentloader-gc
 necko-gc
-layout-suck2
-automatic-garburator.patch
-embedding-print64
-64bit
+# automatic-garburator.patch
 imgcache
 more-xptcall
 shell-loginit
-jscomponentloader-gc2
 console-heapallocate
 compmgr-more
 content-hashtables
-comptr-rewrite.patch2
 xslt-gc
 chromereg-gc
-jscomponentloader-gc3
-xpcomproxy-gcalloc-patch2
 gcobject-nodelete.patch
 root-compmgr
 mark-jsprivate
-xpcomproxy-gcalloc-patch3
-xpconnect-finalization
-root-compmgr2
 root-threads
-configure-with-threadsafe-mmgc
 js-shell-threading
 jsref-with-threadsafe-mmgc
deleted file mode 100644
--- a/xpcomproxy-gcalloc-patch2
+++ /dev/null
@@ -1,21 +0,0 @@
-diff --git a/xpcom/proxy/src/nsProxyEventPrivate.h b/xpcom/proxy/src/nsProxyEventPrivate.h
---- a/xpcom/proxy/src/nsProxyEventPrivate.h
-+++ b/xpcom/proxy/src/nsProxyEventPrivate.h
-@@ -51,7 +51,7 @@
- #include "nsCOMPtr.h"
- #include "nsThreadUtils.h"
- 
--#include "nsClassHashtable.h"
-+#include "nsInterfaceHashtable.h"
- #include "nsHashtable.h"
- 
- #include "prmon.h"
-@@ -293,7 +293,7 @@ private:
- 
-     static nsProxyObjectManager* mInstance;
-     nsHashtable  mProxyObjectMap;
--    nsClassHashtable<nsIDHashKey, nsProxyEventClass> mProxyClassMap;
-+    nsInterfaceHashtable<nsIDHashKey, nsProxyEventClass> mProxyClassMap;
-     PRLock *mProxyCreationLock;
- };
- 
deleted file mode 100644
--- a/xpcomproxy-gcalloc-patch3
+++ /dev/null
@@ -1,44 +0,0 @@
-diff --git a/xpcom/proxy/src/nsProxyEvent.cpp b/xpcom/proxy/src/nsProxyEvent.cpp
---- a/xpcom/proxy/src/nsProxyEvent.cpp
-+++ b/xpcom/proxy/src/nsProxyEvent.cpp
-@@ -109,7 +109,6 @@ nsProxyCallCompletedEvent::QueryInterfac
-     // needs to be allowed through during a synchronous proxy call.
-     if (aIID.Equals(kFilterIID)) {
-         *aResult = mInfo;
--        mInfo->AddRef();
-         return NS_OK;
-     }
-     return nsRunnable::QueryInterface(aIID, aResult);
-@@ -162,7 +161,6 @@ nsProxyObjectCallInfo::QueryInterface(RE
- {
-     if (aIID.Equals(kFilterIID)) {
-         *aResult = this;
--        AddRef();
-         return NS_OK;
-     }
-     return nsRunnable::QueryInterface(aIID, aResult);
-@@ -317,10 +315,6 @@ nsProxyObject::nsProxyObject(nsIEventTar
-     NS_ASSERTION(target == canonicalTarget,
-                  "Non-canonical nsISupports passed to nsProxyObject constructor");
- #endif
--
--    nsProxyObjectManager *pom = nsProxyObjectManager::GetInstance();
--    NS_ASSERTION(pom, "Creating a proxy without a global proxy-object-manager.");
--    pom->AddRef();
- }
- 
- nsProxyObject::~nsProxyObject()
-@@ -335,13 +329,11 @@ nsProxyObject::QueryInterface(REFNSIID a
- {
-     if (aIID.Equals(GetIID())) {
-         *aResult = this;
--        AddRef();
-         return NS_OK;
-     }
- 
-     if (aIID.Equals(NS_GET_IID(nsISupports))) {
-         *aResult = static_cast<nsISupports*>(this);
--        AddRef();
-         return NS_OK;
-     }
- 
--- a/xpcomproxy-gcalloc.patch
+++ b/xpcomproxy-gcalloc.patch
@@ -1,8 +1,55 @@
+* * *
+* * *
+
+diff --git a/xpcom/proxy/src/nsProxyEvent.cpp b/xpcom/proxy/src/nsProxyEvent.cpp
+--- a/xpcom/proxy/src/nsProxyEvent.cpp
++++ b/xpcom/proxy/src/nsProxyEvent.cpp
+@@ -109,7 +109,6 @@ nsProxyCallCompletedEvent::QueryInterfac
+     // needs to be allowed through during a synchronous proxy call.
+     if (aIID.Equals(kFilterIID)) {
+         *aResult = mInfo;
+-        mInfo->AddRef();
+         return NS_OK;
+     }
+     return nsRunnable::QueryInterface(aIID, aResult);
+@@ -162,7 +161,6 @@ nsProxyObjectCallInfo::QueryInterface(RE
+ {
+     if (aIID.Equals(kFilterIID)) {
+         *aResult = this;
+-        AddRef();
+         return NS_OK;
+     }
+     return nsRunnable::QueryInterface(aIID, aResult);
+@@ -317,10 +315,6 @@ nsProxyObject::nsProxyObject(nsIEventTar
+     NS_ASSERTION(target == canonicalTarget,
+                  "Non-canonical nsISupports passed to nsProxyObject constructor");
+ #endif
+-
+-    nsProxyObjectManager *pom = nsProxyObjectManager::GetInstance();
+-    NS_ASSERTION(pom, "Creating a proxy without a global proxy-object-manager.");
+-    pom->AddRef();
+ }
+ 
+ nsProxyObject::~nsProxyObject()
+@@ -335,13 +329,11 @@ nsProxyObject::QueryInterface(REFNSIID a
+ {
+     if (aIID.Equals(GetIID())) {
+         *aResult = this;
+-        AddRef();
+         return NS_OK;
+     }
+ 
+     if (aIID.Equals(NS_GET_IID(nsISupports))) {
+         *aResult = static_cast<nsISupports*>(this);
+-        AddRef();
+         return NS_OK;
+     }
+ 
 diff --git a/xpcom/proxy/src/nsProxyEventClass.cpp b/xpcom/proxy/src/nsProxyEventClass.cpp
 --- a/xpcom/proxy/src/nsProxyEventClass.cpp
 +++ b/xpcom/proxy/src/nsProxyEventClass.cpp
 @@ -70,10 +70,9 @@ nsProxyEventClass::nsProxyEventClass(REF
          if(methodCount)
          {
              int wordCount = (methodCount/32)+1;
 -            if(NULL != (mDescriptors = new uint32[wordCount]))
@@ -20,16 +67,25 @@ diff --git a/xpcom/proxy/src/nsProxyEven
  nsProxyEventClass::~nsProxyEventClass()
  {
 -    if (mDescriptors && mDescriptors != &zero_methods_descriptor)
 -        delete [] mDescriptors;
  }
 diff --git a/xpcom/proxy/src/nsProxyEventPrivate.h b/xpcom/proxy/src/nsProxyEventPrivate.h
 --- a/xpcom/proxy/src/nsProxyEventPrivate.h
 +++ b/xpcom/proxy/src/nsProxyEventPrivate.h
+@@ -51,7 +51,7 @@
+ #include "nsCOMPtr.h"
+ #include "nsThreadUtils.h"
+ 
+-#include "nsClassHashtable.h"
++#include "nsInterfaceHashtable.h"
+ #include "nsHashtable.h"
+ 
+ #include "prmon.h"
 @@ -81,7 +81,7 @@ typedef nsISupports nsISomeInterface;
   * An object representing an IID and its associated interfaceinfo. Instances
   * of this class are obtained via nsProxyObjectManager::GetClass.
   */
 -class nsProxyEventClass
 +class nsProxyEventClass : public XPCOMGCObject
  {
  public:
@@ -38,8 +94,17 @@ diff --git a/xpcom/proxy/src/nsProxyEven
  
      nsIID                      mIID;
      nsCOMPtr<nsIInterfaceInfo> mInfo;
 -    uint32*                    mDescriptors;
 +    uint32*                    mDescriptors; // GC-allocated
  };
  
  /**
+@@ -293,7 +293,7 @@ private:
+ 
+     static nsProxyObjectManager* mInstance;
+     nsHashtable  mProxyObjectMap;
+-    nsClassHashtable<nsIDHashKey, nsProxyEventClass> mProxyClassMap;
++    nsInterfaceHashtable<nsIDHashKey, nsProxyEventClass> mProxyClassMap;
+     PRLock *mProxyCreationLock;
+ };
+ 
--- a/xpconnect-allocations
+++ b/xpconnect-allocations
@@ -1,39 +1,933 @@
+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
+@@ -808,6 +808,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;
+@@ -824,7 +828,7 @@ XPC_XOW_Finalize(JSContext *cx, JSObject
+   // entirely. Scope can be null if we're an enumerating XOW.
+   XPCWrappedNativeScope *scope = reinterpret_cast<XPCWrappedNativeScope *>
+                                                  (JSVAL_TO_PRIVATE(scopeVal));
+-  if (!scope || XPCWrappedNativeScope::IsDyingScope(scope)) {
++  if (!scope) {
+     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
+@@ -811,7 +811,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;
+@@ -1371,7 +1371,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);
+@@ -1426,23 +1426,15 @@ NS_IMETHODIMP
+ NS_IMETHODIMP 
+ nsXPConnect::GetDeferReleasesUntilAfterGarbageCollection(PRBool *aDeferReleasesUntilAfterGarbageCollection)
+ {
+-    XPCJSRuntime* rt = GetRuntime();
+-    if(!rt)
+-        return UnexpectedFailure(NS_ERROR_FAILURE);
+-
+-    *aDeferReleasesUntilAfterGarbageCollection = rt->GetDeferReleases();
+-    return NS_OK;
++    NS_ERROR("Nonsense method.");
++    return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ 
+ NS_IMETHODIMP 
+ nsXPConnect::SetDeferReleasesUntilAfterGarbageCollection(PRBool aDeferReleasesUntilAfterGarbageCollection)
+ {
+-    XPCJSRuntime* rt = GetRuntime();
+-    if(!rt)
+-        return UnexpectedFailure(NS_ERROR_FAILURE);
+-
+-    rt->SetDeferReleases(aDeferReleasesUntilAfterGarbageCollection);
+-    return NS_OK;
++    NS_ERROR("Nonsense method.");
++    return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ 
+ /* void releaseJSContext (in JSContextPtr aJSContext, in PRBool noGC); */
+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
+@@ -4010,7 +4010,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/xpcconvert.cpp b/js/src/xpconnect/src/xpcconvert.cpp
+--- a/js/src/xpconnect/src/xpcconvert.cpp
++++ b/js/src/xpconnect/src/xpcconvert.cpp
+@@ -1094,7 +1094,7 @@ XPCConvert::NativeInterface2JSObject(XPC
+         if(!xpcscope)
+             return JS_FALSE;
+ 
+-        AutoMarkingNativeInterfacePtr iface(ccx);
++        XPCNativeInterface* iface;
+         iface = XPCNativeInterface::GetNewOrUsed(ccx, iid);
+         if(!iface)
+             return JS_FALSE;
+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
+@@ -487,7 +487,7 @@ nsJSIID::NewResolve(nsIXPConnectWrappedN
+ {
+     XPCCallContext ccx(JS_CALLER, cx);
+ 
+-    AutoMarkingNativeInterfacePtr iface(ccx);
++    XPCNativeInterface* iface;
+ 
+     const nsIID* iid;
+     mInfo->GetIIDShared(&iid);
+@@ -529,7 +529,7 @@ nsJSIID::Enumerate(nsIXPConnectWrappedNa
+ 
+     XPCCallContext ccx(JS_CALLER, cx);
+ 
+-    AutoMarkingNativeInterfacePtr iface(ccx);
++    XPCNativeInterface* iface;
+ 
+     const nsIID* iid;
+     mInfo->GetIIDShared(&iid);
+@@ -590,7 +590,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))
+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())
+-    {
+-        set->Unmark();
++    if(NS_GetGC()->GetMark(set))
++    {
+         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
+@@ -316,27 +255,6 @@ JSBool XPCJSRuntime::GCCallback(JSContex
+                     self->mThreadRunningGC = PR_GetCurrentThread();
+                 }
+ 
+-                dyingWrappedJSArray = &self->mWrappedJSToReleaseArray;
+-                {
+-                    XPCLock* lock = self->GetMainThreadOnlyGC() ?
+-                                    nsnull : self->GetMapLock();
+-
+-                    XPCAutoLock al(lock); // lock the wrapper map if necessary
+-                    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
+@@ -346,7 +264,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;
+@@ -388,15 +308,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,
+@@ -421,28 +332,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();
+-                            }
+                         }
+                     }
+                 }
+@@ -461,18 +350,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();
+@@ -484,81 +361,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.
+@@ -573,42 +375,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.
+-
+-                XPCLock* lock = self->GetMainThreadOnlyGC() ?
+-                                nsnull : self->GetMapLock();
+-
+-                // Do any deferred released of native objects.
+-                if(self->GetDeferReleases())
+-                {
+-                    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;
+-                        {
+-                            XPCAutoLock al(lock); // lock if necessary
+-                            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:
+@@ -832,7 +598,6 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
+    mWrappedJSToReleaseArray(),
+    mNativesToReleaseArray(),
+    mMainThreadOnlyGC(JS_FALSE),
+-   mDeferReleases(JS_FALSE),
+    mDoingFinalization(JS_FALSE),
+    mVariantRoots(nsnull),
+    mWrappedJSRoots(nsnull),
+@@ -1019,26 +784,6 @@ XPCJSRuntime::GenerateStringIDs(JSContex
+     return JS_TRUE;
+ }
+ 
+-JSBool
+-XPCJSRuntime::DeferredRelease(nsISupports* obj)
+-{
+-    NS_ASSERTION(obj, "bad param");
+-    NS_ASSERTION(GetDeferReleases(), "bad call");
+-
+-    XPCLock* lock = GetMainThreadOnlyGC() ? nsnull : GetMapLock();
+-    {
+-        XPCAutoLock al(lock); // lock if necessary
+-        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);
+-    }        
+-}
+-
+ /***************************************************************************/
+ 
+ #ifdef DEBUG
+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
+@@ -198,6 +198,29 @@ 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->key))
++    {
++        NS_ASSERTION(NS_GetGC()->GetMark(entry->value),
++                     "In Native2WrappedNativeMap::DyingUnmapper key was marked but not value.");
++
++        return JS_DHASH_NEXT;
++    }
++
++    NS_ASSERTION(!NS_GetGC()->GetMark(entry->value),
++                 "In Native2WrappedNativeMap::DyingUnmapper value was marked but not key.");
++
++    return JS_DHASH_REMOVE;
++}
++
+ /***************************************************************************/
+ // implement IID2WrappedJSClassMap...
+ 
+@@ -321,6 +344,28 @@ 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->key))
++    {
++        NS_ASSERTION(NS_GetGC()->GetMark(entry->value),
++                     "In ClassInfo2WrappedNativeProtoMap::DyingUnmapper key was marked but not value.");
++
++        return JS_DHASH_NEXT;
++    }
++
++    NS_ASSERTION(!NS_GetGC()->GetMark(entry->value),
++                 "In ClassInfo2WrappedNativeProtoMap::DyingUnmapper value was marked but not key.");
++
++    return JS_DHASH_REMOVE;
+ }
+ 
+ /***************************************************************************/
+@@ -675,4 +720,28 @@ WrappedNative2WrapperMap::~WrappedNative
+         JS_DHashTableDestroy(mTable);
+ }
+ 
+-/***************************************************************************/
++// static
++JSDHashOperator
++WrappedNative2WrapperMap::DyingUnmapper(JSDHashTable *table,
++                                        JSDHashEntryHdr *hdr,
++                                        uint32 number,
++                                        void *arg)
++{
++    Entry *entry = static_cast<Entry*>(hdr);
++
++    if(NS_GetGC()->GetMark(entry->key))
++    {
++        NS_ASSERTION(NS_GetGC()->GetMark(entry->value),
++                     "In WrappedNative2WrapperMap::DyingUnmapper key was marked but not value.");
++        
++        return JS_DHASH_NEXT;
++    }
++
++    NS_ASSERTION(!NS_GetGC()->GetMark(entry->value),
++                 "In WrappedNative2WrappedMap::DyingUnmapper value was marked but not key.");
++
++    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
+@@ -207,6 +207,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);}
+@@ -215,6 +220,11 @@ private:
+ private:
+     Native2WrappedNativeMap();    // no implementation
+     Native2WrappedNativeMap(int size);
++
++    static JSDHashOperator DyingUnmapper(JSDHashTable *table,
++                                         JSDHashEntryHdr *hdr,
++                                         uint32 number,
++                                         void *arg);
+ private:
+     JSDHashTable *mTable;
+ };
+@@ -429,6 +439,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);}
+@@ -437,6 +452,12 @@ private:
+ private:
+     ClassInfo2WrappedNativeProtoMap();    // no implementation
+     ClassInfo2WrappedNativeProtoMap(int size);
++
++    static JSDHashOperator DyingUnmapper(JSDHashTable *table,
++                                         JSDHashEntryHdr *hdr,
++                                         uint32 number,
++                                         void *arg);
++
+ private:
+     JSDHashTable *mTable;
+ };
+@@ -728,6 +749,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);}
+@@ -736,6 +762,11 @@ private:
+ 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
-@@ -857,7 +857,7 @@ private:
+@@ -596,15 +596,6 @@ public:
+     JSBool GetMainThreadOnlyGC() const   {return mMainThreadOnlyGC;}
+     void   SetMainThreadOnlyGC(JSBool b) {mMainThreadOnlyGC = b;}
+     
+-    JSBool GetDeferReleases() const {return mDeferReleases;}
+-    void   SetDeferReleases(JSBool b) 
+-        {/* If deferring is turned off while any are pending they'll leak! */
+-         NS_ASSERTION((mDeferReleases && b) || 
+-                      !mNativesToReleaseArray.Count(), "bad"); 
+-         mDeferReleases = b;}
+-
+-    JSBool DeferredRelease(nsISupports* obj);
+-
+     JSBool GetDoingFinalization() const {return mDoingFinalization;}
+ 
+     // Mapping of often used strings to jsid atoms that live 'forever'.
+@@ -717,7 +708,6 @@ private:
+     nsVoidArray mWrappedJSToReleaseArray;
+     nsVoidArray mNativesToReleaseArray;
+     JSBool mMainThreadOnlyGC;
+-    JSBool mDeferReleases;
+     JSBool mDoingFinalization;
+     XPCRootSetElem *mVariantRoots;
+     XPCRootSetElem *mWrappedJSRoots;
+@@ -857,7 +847,7 @@ private:
  //
  // Note that most accessors are inlined.
  
 -class XPCCallContext : public XPCOMGCFinalizedObject, public nsIXPCNativeCallContext
 +class XPCCallContext : public nsIXPCNativeCallContext
  {
  public:
      NS_DECL_ISUPPORTS
-@@ -1075,7 +1075,7 @@ xpc_TraceForValidWrapper(JSTracer *trc, 
+@@ -1075,7 +1065,7 @@ xpc_TraceForValidWrapper(JSTracer *trc, 
  /***************************************************************************/
  // XPCWrappedNativeScope is one-to-one with a JS global object.
  
 -class XPCWrappedNativeScope
 +class XPCWrappedNativeScope : XPCOMGCFinalizedObject, MMgc::GCFinalizable
  {
  public:
  
-@@ -1292,7 +1292,7 @@ private:
+@@ -1115,6 +1105,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);
+@@ -1123,28 +1119,11 @@ public:
+     SystemIsBeingShutDown(JSContext* cx);
+ 
+     static void
+-    SuspectAllWrappers(XPCJSRuntime* rt);
+-
+-    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);
+ 
+@@ -1154,13 +1133,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; }
+ 
+ #ifndef XPCONNECT_STANDALONE
+     /**
+@@ -1173,13 +1149,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;
+@@ -1292,7 +1265,7 @@ private:
  
  // Tight. No virtual methods.
  
 -class XPCNativeInterface
 +class XPCNativeInterface : XPCOMGCObject
  {
  public:
      static XPCNativeInterface* GetNewOrUsed(XPCCallContext& ccx,
-@@ -1346,12 +1346,21 @@ protected:
+@@ -1316,7 +1289,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];}
+ 
+@@ -1326,17 +1299,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,
+@@ -1346,12 +1312,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
@@ -48,85 +942,1117 @@ diff --git a/js/src/xpconnect/src/xpcpri
 +
 +    static void operator delete(void *obj)
 +    {
 +        MMgc::GCObject::operator delete(obj);
 +    }
  
  private:
      nsCOMPtr<nsIInterfaceInfo> mInfo;
-@@ -1614,7 +1623,7 @@ private:
+@@ -1413,7 +1388,7 @@ private:
+ /***************************************************************************/
+ // XPCNativeSet represents an ordered collection of XPCNativeInterface pointers.
+ 
+-class XPCNativeSet
++class XPCNativeSet : XPCOMGCObject
+ {
+ public:
+     static XPCNativeSet* GetNewOrUsed(XPCCallContext& ccx, const nsIID* iid);
+@@ -1458,12 +1433,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:
+@@ -1471,13 +1440,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,
+@@ -1486,9 +1449,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;
+@@ -1614,7 +1575,7 @@ private:
  // XPCNativeScriptableInfo is used to hold the nsIXPCScriptable state for a
  // given class or instance.
  
 -class XPCNativeScriptableInfo
 +class XPCNativeScriptableInfo : XPCOMGCObject
  {
  public:
      static XPCNativeScriptableInfo*
-@@ -1644,10 +1653,8 @@ protected:
+@@ -1644,10 +1605,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
-@@ -1688,7 +1695,7 @@ public:
+@@ -1688,7 +1647,7 @@ public:
      SetFlags(const XPCNativeScriptableFlags& flags)  {mFlags = flags;}
  
  private:
 -    nsCOMPtr<nsIXPCScriptable>  mCallback;
 +    nsIXPCScriptable*           mCallback;
      XPCNativeScriptableFlags    mFlags;
  };
  
-@@ -1696,7 +1703,7 @@ private:
+@@ -1696,7 +1655,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*
+@@ -1761,29 +1720,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:
+@@ -1820,6 +1756,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:
+@@ -1836,18 +1775,6 @@ public:
+     void SetJSObject(JSObject*  JSObj);
+ 
+     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
+@@ -1860,6 +1787,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
+ 
+@@ -1887,6 +1823,10 @@ private:
+ private:
+     XPCWrappedNativeTearOffChunk() : mNextChunk(nsnull) {}
+     ~XPCWrappedNativeTearOffChunk() {delete mNextChunk;}
++
++    static void* operator new(size_t size) {
++        return XPCOMGCObject::operator new(size);
++    }
+ 
+ private:
+     XPCWrappedNativeTearOff mTearOffs[XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK];
+@@ -2058,21 +1998,9 @@ public:
+                                          XPCNativeInterface* aInterface,
+                                          JSBool needJSObject = JS_FALSE,
+                                          nsresult* pError = nsnull);
+-    void Mark() const
+-    {
+-        mSet->Mark();
+-        if(mScriptableInfo) mScriptableInfo->Mark();
+-        if(HasProto()) mMaybeProto->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()) mMaybeProto->TraceJS(trc);
+-        if(mWrapper)
+-            JS_CALL_OBJECT_TRACER(trc, mWrapper, "XPCWrappedNative::mWrapper");
+         TraceOtherWrapper(trc);
+     }
+ 
+@@ -2091,16 +2019,10 @@ public:
+     }
+ 
+ #ifdef DEBUG
+-    void ASSERT_SetsNotMarked() const
+-        {mSet->ASSERT_NotMarked();
+-         if(HasProto()){mMaybeProto->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,
+@@ -3506,11 +3428,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_)                    \
+@@ -3565,9 +3482,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
+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
+@@ -297,19 +297,8 @@ nsXPCWrappedJS::~nsXPCWrappedJS()
+ 
+     if(IsValid())
+     {
+-        NS_IF_RELEASE(mClass);
+-        if (mOuter)
+-        {
+-            if (rt && rt->GetThreadRunningGC())
+-            {
+-                rt->DeferredRelease(mOuter);
+-                mOuter = nsnull;
+-            }
+-            else
+-            {
+-                NS_RELEASE(mOuter);
+-            }
+-        }
++        mClass = nsnull;
++        mOuter = nsnull;
+     }
+ }
+ 
+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)
+@@ -407,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;
+     }
+@@ -447,8 +442,6 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
+ 
+     if(wrapperToKill)
+     {
+-        // Second reference will be released by the FlatJSObject's finializer.
+-        wrapperToKill->Release();
+     }
+     else if(wrapper)
+     {
+@@ -466,7 +459,6 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
+                     map->Remove(wrapper);
+                 }
+ 
+-                wrapper->Release();
+                 return rv;
+             }
+         }
+@@ -569,38 +561,17 @@ XPCWrappedNative::~XPCWrappedNative()
+ {
+     DEBUG_TrackDeleteWrapper(this);
+ 
+-    XPCWrappedNativeProto* proto = GetProto();
+-
+-    if(mScriptableInfo &&
+-       (!HasProto() ||
+-        (proto && proto->GetScriptableInfo() != mScriptableInfo)))
+-    {
+-        delete mScriptableInfo;
+-    }
+-
+-    Native2WrappedNativeMap* map = GetScope()->GetWrappedNativeMap();
+-    {   // scoped lock
+-        XPCAutoLock lock(GetRuntime()->GetMapLock());
+-        map->Remove(this);
+-    }
+-
+-    if(mIdentity)
+-    {
+-        XPCJSRuntime* rt = GetRuntime();
+-        if(rt && rt->GetDeferReleases() && 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);
+-        }
+-    }
++#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
++
++    mIdentity = nsnull;
+ }
+ 
+ // This is factored out so that it can be called publicly 
+@@ -917,31 +888,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 && rt->GetDeferReleases())
+-                {
+-                    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);
+         }
+     }
+@@ -951,17 +898,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
+@@ -1073,8 +1011,8 @@ XPCWrappedNative::ReparentWrapperIfFound
+     {
+         // Oh, so now we need to move the wrapper to a different scope.
+ 
+-        AutoMarkingWrappedNativeProtoPtr oldProto(ccx);
+-        AutoMarkingWrappedNativeProtoPtr newProto(ccx);
++        XPCWrappedNativeProto* oldProto = nsnull;
++        XPCWrappedNativeProto* newProto = nsnull;
+ 
+         if(wrapper->HasProto())
+         {
+@@ -1322,7 +1260,7 @@ XPCWrappedNative::ExtendSet(XPCCallConte
+ 
+     if(!mSet->HasInterface(aInterface))
+     {
+-        AutoMarkingNativeSetPtr newSet(ccx);
++        XPCNativeSet* newSet;
+         newSet = XPCNativeSet::GetNewOrUsed(ccx, mSet, aInterface,
+                                             mSet->GetInterfaceCount());
+         if(!newSet)
+@@ -1393,13 +1331,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;
+                 }
+@@ -1427,12 +1363,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;
+     }
+@@ -2423,8 +2354,6 @@ done:
+             }
+             else if(dp->IsValAllocated())
+                 nsMemory::Free(p);
+-            else if(dp->IsValInterface())
+-                ((nsISupports*)p)->Release();
+             else if(dp->IsValDOMString())
+                 delete (nsAString*)p;
+             else if(dp->IsValUTF8String())
+@@ -2543,8 +2472,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();
+ 
+@@ -2560,7 +2489,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
-@@ -471,14 +471,7 @@ XPCNativeInterface::NewInstance(XPCCallC
+@@ -213,7 +213,7 @@ XPCNativeInterface*
+ XPCNativeInterface*
+ XPCNativeInterface::GetNewOrUsed(XPCCallContext& ccx, const nsIID* iid)
+ {
+-    AutoMarkingNativeInterfacePtr iface(ccx);
++    XPCNativeInterface* iface;
+     XPCJSRuntime* rt = ccx.GetRuntime();
+ 
+     IID2NativeInterfaceMap* map = rt->GetIID2NativeInterfaceMap();
+@@ -243,12 +243,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;
+         }
+     }
+@@ -260,7 +258,7 @@ XPCNativeInterface*
+ XPCNativeInterface*
+ XPCNativeInterface::GetNewOrUsed(XPCCallContext& ccx, nsIInterfaceInfo* info)
+ {
+-    AutoMarkingNativeInterfacePtr iface(ccx);
++    XPCNativeInterface* iface;
+ 
+     const nsIID* iid;
+     if(NS_FAILED(info->GetIIDShared(&iid)) || !iid)
+@@ -290,12 +288,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;
+         }
+     }
+@@ -471,14 +467,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)
          {
-@@ -501,8 +494,7 @@ XPCNativeInterface::DestroyInstance(JSCo
- XPCNativeInterface::DestroyInstance(JSContext* cx, XPCJSRuntime* rt,
-                                     XPCNativeInterface* inst)
- {
+@@ -494,15 +483,6 @@ XPCNativeInterface::NewInstance(XPCCallC
+         delete [] members;
+ 
+     return obj;
+-}
+-
+-// static
+-void
+-XPCNativeInterface::DestroyInstance(JSContext* cx, XPCJSRuntime* rt,
+-                                    XPCNativeInterface* inst)
+-{
 -    inst->~XPCNativeInterface();
 -    delete [] (char*) inst;
-+    delete inst;
  }
  
  const char*
+@@ -533,9 +513,9 @@ XPCNativeSet*
+ XPCNativeSet*
+ XPCNativeSet::GetNewOrUsed(XPCCallContext& ccx, const nsIID* iid)
+ {
+-    AutoMarkingNativeSetPtr set(ccx);
+-
+-    AutoMarkingNativeInterfacePtr iface(ccx);
++    XPCNativeSet* set = nsnull;
++
++    XPCNativeInterface* iface;
+     iface = XPCNativeInterface::GetNewOrUsed(ccx, iid);
+     if(!iface)
+         return nsnull;
+@@ -567,12 +547,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;
+         }
+     }
+@@ -584,7 +562,7 @@ XPCNativeSet*
+ XPCNativeSet*
+ XPCNativeSet::GetNewOrUsed(XPCCallContext& ccx, nsIClassInfo* classInfo)
+ {
+-    AutoMarkingNativeSetPtr set(ccx);
++    XPCNativeSet* set = nsnull;
+     XPCJSRuntime* rt = ccx.GetRuntime();
+ 
+     ClassInfo2NativeSetMap* map = rt->GetClassInfo2NativeSetMap();
+@@ -600,7 +578,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)))
+@@ -620,12 +599,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;
+@@ -669,13 +648,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;
+                     }
+                 }
+@@ -699,7 +676,7 @@ out:
+     if(iidArray)
+         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(iidCount, iidArray);
+     if(interfaceArray)
+-        delete [] interfaceArray.get();
++        NS_GetGC()->Free(interfaceArray);
+ 
+     return set;
+ }
+@@ -726,7 +703,7 @@ XPCNativeSet::GetNewOrUsed(XPCCallContex
+                            XPCNativeInterface* newInterface,
+                            PRUint16 position)
+ {
+-    AutoMarkingNativeSetPtr set(ccx);
++    XPCNativeSet* set;
+     XPCJSRuntime* rt = ccx.GetRuntime();
+     NativeSetMap* map = rt->GetNativeSetMap();
+     if(!map)
+@@ -756,12 +733,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;
+         }
+     }
+@@ -797,14 +772,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)
+     {
+@@ -846,12 +814,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)
+     {
+@@ -882,12 +849,15 @@ XPCNativeSet::NewInstanceMutate(XPCNativ
+     return obj;
+ }
+ 
+-// static
+-void
+-XPCNativeSet::DestroyInstance(XPCNativeSet* inst)
+-{
+-    inst->~XPCNativeSet();
+-    delete [] (char*) inst;
++void*
++XPCNativeSet::operator new(size_t size, PRUint16 interfaceCount)
++{
++    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;
+ 
+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
+@@ -179,7 +179,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;
+@@ -218,7 +218,7 @@ XPCWrappedNativeProto::GetNewOrUsed(XPCC
+         }
+     }
+ 
+-    AutoMarkingNativeSetPtr set(ccx);
++    XPCNativeSet* set;
+     set = XPCNativeSet::GetNewOrUsed(ccx, ClassInfo);
+     if(!set)
+         return nsnull;
+@@ -227,7 +227,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
+@@ -107,7 +107,6 @@ static void DEBUG_TrackScopeShutdown()
+ /***************************************************************************/
+ 
+ XPCWrappedNativeScope* XPCWrappedNativeScope::gScopes = nsnull;
+-XPCWrappedNativeScope* XPCWrappedNativeScope::gDyingScopes = nsnull;
+ 
+ // static
+ XPCWrappedNativeScope*
+@@ -159,18 +158,6 @@ XPCWrappedNativeScope::XPCWrappedNativeS
+ 
+     DEBUG_TrackNewScope(this);
+     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
+@@ -255,6 +242,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");
+@@ -277,167 +271,40 @@ XPCWrappedNativeScope::~XPCWrappedNative
+     NS_IF_RELEASE(mComponents);
+ }
+ 
++
++
++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());
+-
+-    // 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)
+-    {
+-        XPCWrappedNativeScope* next = cur->mNext;
+-        if(cur->mGlobalJSObject &&
+-           JS_IsAboutToBeFinalized(cx, cur->mGlobalJSObject))
+-        {
+-            cur->mGlobalJSObject = nsnull;
+-
+-            // Move this scope from the live list to the dying list.
++
++    for(XPCWrappedNativeScope *cur = gScopes;
++        cur;
++        prev = cur, cur = cur->mNext)
++    {
++        if(NS_GetGC()->GetMark(cur))
++        {
++            // If the scope is marked, regulate its maps
++            cur->UnmapDyingNatives();
++        }
++        else
++        {
++            // If the scope is not marked, remove it from our linked list
+             if(prev)
+-                prev->mNext = next;
++                prev->mNext = cur->mNext;
+             else
+-                gScopes = next;
+-            cur->mNext = gDyingScopes;
+-            gDyingScopes = cur;
+-            cur = nsnull;
+-        }
+-        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)
+-            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;
++                gScopes = cur->mNext;
++        }
++    }
+ }
+ 
+ struct ShutdownData
+@@ -486,28 +353,15 @@ XPCWrappedNativeScope::SystemIsBeingShut
+     DEBUG_TrackScopeTraversal();
+     DEBUG_TrackScopeShutdown();
+ 
+-    int liveScopeCount = 0;
+-
+     ShutdownData data(cx);
+ 
+-    XPCWrappedNativeScope* cur;
+-
+-    // 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++;
+-    }
++    XPCWrappedNativeScope* cur = gScopes;
++
+     gScopes = nsnull;
+ 
+-    // Walk the unified dying list and call shutdown on all wrappers and protos
+-
+-    for(cur = gDyingScopes; cur; cur = cur->mNext)
++    // Walk the list of scopes and call shutdown on all wrappers and protos
++
++    for(; cur; cur = cur->mNext)
+     {
+         // Give the Components object a chance to try to clean up.
+         if(cur->mComponents)
+@@ -520,9 +374,6 @@ XPCWrappedNativeScope::SystemIsBeingShut
+         cur->mWrappedNativeMap->
+                 Enumerate(WrappedNativeShutdownEnumerator,  &data);
+     }
+-
+-    // Now it is safe to kill all the scopes.
+-    KillDyingScopes();
+ 
+ #ifdef XPC_DUMP_AT_SHUTDOWN
+     if(data.wrapperCount)
+@@ -532,9 +383,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
+ }
+ 
+@@ -726,7 +574,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
 @@ -92,14 +92,13 @@ public:
  
      NS_DECL_NSIMODULE
  
 -    struct FactoryNode
deleted file mode 100644
--- a/xpconnect-finalization
+++ /dev/null
@@ -1,1936 +0,0 @@
-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
-@@ -808,6 +808,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;
-@@ -824,7 +828,7 @@ XPC_XOW_Finalize(JSContext *cx, JSObject
-   // entirely. Scope can be null if we're an enumerating XOW.
-   XPCWrappedNativeScope *scope = reinterpret_cast<XPCWrappedNativeScope *>
-                                                  (JSVAL_TO_PRIVATE(scopeVal));
--  if (!scope || XPCWrappedNativeScope::IsDyingScope(scope)) {
-+  if (!scope) {
-     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
-@@ -811,7 +811,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;
-@@ -1371,7 +1371,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);
-@@ -1426,23 +1426,15 @@ NS_IMETHODIMP
- NS_IMETHODIMP 
- nsXPConnect::GetDeferReleasesUntilAfterGarbageCollection(PRBool *aDeferReleasesUntilAfterGarbageCollection)
- {
--    XPCJSRuntime* rt = GetRuntime();
--    if(!rt)
--        return UnexpectedFailure(NS_ERROR_FAILURE);
--
--    *aDeferReleasesUntilAfterGarbageCollection = rt->GetDeferReleases();
--    return NS_OK;
-+    NS_ERROR("Nonsense method.");
-+    return NS_ERROR_NOT_IMPLEMENTED;
- }
- 
- NS_IMETHODIMP 
- nsXPConnect::SetDeferReleasesUntilAfterGarbageCollection(PRBool aDeferReleasesUntilAfterGarbageCollection)
- {
--    XPCJSRuntime* rt = GetRuntime();
--    if(!rt)
--        return UnexpectedFailure(NS_ERROR_FAILURE);
--
--    rt->SetDeferReleases(aDeferReleasesUntilAfterGarbageCollection);
--    return NS_OK;
-+    NS_ERROR("Nonsense method.");
-+    return NS_ERROR_NOT_IMPLEMENTED;
- }
- 
- /* void releaseJSContext (in JSContextPtr aJSContext, in PRBool noGC); */
-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
-@@ -4010,7 +4010,7 @@ nsXPCComponents::AttachNewComponentsObje
- 
-     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/xpcconvert.cpp b/js/src/xpconnect/src/xpcconvert.cpp
---- a/js/src/xpconnect/src/xpcconvert.cpp
-+++ b/js/src/xpconnect/src/xpcconvert.cpp
-@@ -1094,7 +1094,7 @@ XPCConvert::NativeInterface2JSObject(XPC
-         if(!xpcscope)
-             return JS_FALSE;
- 
--        AutoMarkingNativeInterfacePtr iface(ccx);
-+        XPCNativeInterface* iface;
-         iface = XPCNativeInterface::GetNewOrUsed(ccx, iid);
-         if(!iface)
-             return JS_FALSE;
-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
-@@ -487,7 +487,7 @@ nsJSIID::NewResolve(nsIXPConnectWrappedN
- {
-     XPCCallContext ccx(JS_CALLER, cx);
- 
--    AutoMarkingNativeInterfacePtr iface(ccx);
-+    XPCNativeInterface* iface;
- 
-     const nsIID* iid;
-     mInfo->GetIIDShared(&iid);
-@@ -529,7 +529,7 @@ nsJSIID::Enumerate(nsIXPConnectWrappedNa
- 
-     XPCCallContext ccx(JS_CALLER, cx);
- 
--    AutoMarkingNativeInterfacePtr iface(ccx);
-+    XPCNativeInterface* iface;
- 
-     const nsIID* iid;
-     mInfo->GetIIDShared(&iid);
-@@ -590,7 +590,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))
-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())
--    {
--        set->Unmark();
-+    if(NS_GetGC()->GetMark(set))
-+    {
-         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;
- }
- 
-@@ -209,17 +159,6 @@ JSClassSweeper(JSDHashTable *table, JSDH
- 
-     delete shared;
-     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
-@@ -306,27 +245,6 @@ JSBool XPCJSRuntime::GCCallback(JSContex
-                     self->mThreadRunningGC = PR_GetCurrentThread();
-                 }
- 
--                dyingWrappedJSArray = &self->mWrappedJSToReleaseArray;
--                {
--                    XPCLock* lock = self->GetMainThreadOnlyGC() ?
--                                    nsnull : self->GetMapLock();
--
--                    XPCAutoLock al(lock); // lock the wrapper map if necessary
--                    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
-@@ -336,7 +254,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;
-@@ -378,15 +298,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,
-@@ -411,28 +322,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();
--                            }
-                         }
-                     }
-                 }
-@@ -451,18 +340,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();
-@@ -474,83 +351,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.
--
--#if 0 // removed by bsmedberg for XPCOMGC
--                self->mDyingWrappedNativeProtoMap->
--                    Enumerate(DyingProtoKiller, nsnull);
--#endif
--
- 
-                 // mThreadRunningGC indicates that GC is running.
-                 // Clear it and notify waiters.
-@@ -565,42 +365,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.
--
--                XPCLock* lock = self->GetMainThreadOnlyGC() ?
--                                nsnull : self->GetMapLock();
--
--                // Do any deferred released of native objects.
--                if(self->GetDeferReleases())
--                {
--                    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;
--                        {
--                            XPCAutoLock al(lock); // lock if necessary
--                            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:
-@@ -824,7 +588,6 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* 
-    mWrappedJSToReleaseArray(),
-    mNativesToReleaseArray(),
-    mMainThreadOnlyGC(JS_FALSE),
--   mDeferReleases(JS_FALSE),
-    mDoingFinalization(JS_FALSE),
-    mVariantRoots(nsnull),
-    mWrappedJSRoots(nsnull),
-@@ -1011,26 +774,6 @@ XPCJSRuntime::GenerateStringIDs(JSContex
-     return JS_TRUE;
- }
- 
--JSBool
--XPCJSRuntime::DeferredRelease(nsISupports* obj)
--{
--    NS_ASSERTION(obj, "bad param");
--    NS_ASSERTION(GetDeferReleases(), "bad call");
--
--    XPCLock* lock = GetMainThreadOnlyGC() ? nsnull : GetMapLock();
--    {
--        XPCAutoLock al(lock); // lock if necessary
--        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);
--    }        
--}
--
- /***************************************************************************/
- 
- #ifdef DEBUG
-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
-@@ -198,6 +198,29 @@ 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->key))
-+    {
-+        NS_ASSERTION(NS_GetGC()->GetMark(entry->value),
-+                     "In Native2WrappedNativeMap::DyingUnmapper key was marked but not value.");
-+
-+        return JS_DHASH_NEXT;
-+    }
-+
-+    NS_ASSERTION(!NS_GetGC()->GetMark(entry->value),
-+                 "In Native2WrappedNativeMap::DyingUnmapper value was marked but not key.");
-+
-+    return JS_DHASH_REMOVE;
-+}
-+
- /***************************************************************************/
- // implement IID2WrappedJSClassMap...
- 
-@@ -321,6 +344,28 @@ 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->key))
-+    {
-+        NS_ASSERTION(NS_GetGC()->GetMark(entry->value),
-+                     "In ClassInfo2WrappedNativeProtoMap::DyingUnmapper key was marked but not value.");
-+
-+        return JS_DHASH_NEXT;
-+    }
-+
-+    NS_ASSERTION(!NS_GetGC()->GetMark(entry->value),
-+                 "In ClassInfo2WrappedNativeProtoMap::DyingUnmapper value was marked but not key.");
-+
-+    return JS_DHASH_REMOVE;
- }
- 
- /***************************************************************************/
-@@ -675,4 +720,28 @@ WrappedNative2WrapperMap::~WrappedNative
-         JS_DHashTableDestroy(mTable);
- }
- 
--/***************************************************************************/
-+// static
-+JSDHashOperator
-+WrappedNative2WrapperMap::DyingUnmapper(JSDHashTable *table,
-+                                        JSDHashEntryHdr *hdr,
-+                                        uint32 number,
-+                                        void *arg)
-+{
-+    Entry *entry = static_cast<Entry*>(hdr);
-+
-+    if(NS_GetGC()->GetMark(entry->key))
-+    {
-+        NS_ASSERTION(NS_GetGC()->GetMark(entry->value),
-+                     "In WrappedNative2WrapperMap::DyingUnmapper key was marked but not value.");
-+        
-+        return JS_DHASH_NEXT;
-+    }
-+
-+    NS_ASSERTION(!NS_GetGC()->GetMark(entry->value),
-+                 "In WrappedNative2WrappedMap::DyingUnmapper value was marked but not key.");
-+
-+    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
-@@ -207,6 +207,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);}
-@@ -215,6 +220,11 @@ private:
- private:
-     Native2WrappedNativeMap();    // no implementation
-     Native2WrappedNativeMap(int size);
-+
-+    static JSDHashOperator DyingUnmapper(JSDHashTable *table,
-+                                         JSDHashEntryHdr *hdr,
-+                                         uint32 number,
-+                                         void *arg);
- private:
-     JSDHashTable *mTable;
- };
-@@ -429,6 +439,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);}
-@@ -437,6 +452,12 @@ private:
- private:
-     ClassInfo2WrappedNativeProtoMap();    // no implementation
-     ClassInfo2WrappedNativeProtoMap(int size);
-+
-+    static JSDHashOperator DyingUnmapper(JSDHashTable *table,
-+                                         JSDHashEntryHdr *hdr,
-+                                         uint32 number,
-+                                         void *arg);
-+
- private:
-     JSDHashTable *mTable;
- };
-@@ -728,6 +749,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);}
-@@ -736,6 +762,11 @@ private:
- 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
-@@ -596,15 +596,6 @@ public:
-     JSBool GetMainThreadOnlyGC() const   {return mMainThreadOnlyGC;}
-     void   SetMainThreadOnlyGC(JSBool b) {mMainThreadOnlyGC = b;}
-     
--    JSBool GetDeferReleases() const {return mDeferReleases;}
--    void   SetDeferReleases(JSBool b) 
--        {/* If deferring is turned off while any are pending they'll leak! */
--         NS_ASSERTION((mDeferReleases && b) || 
--                      !mNativesToReleaseArray.Count(), "bad"); 
--         mDeferReleases = b;}
--
--    JSBool DeferredRelease(nsISupports* obj);
--
-     JSBool GetDoingFinalization() const {return mDoingFinalization;}
- 
-     // Mapping of often used strings to jsid atoms that live 'forever'.
-@@ -717,7 +708,6 @@ private:
-     nsVoidArray mWrappedJSToReleaseArray;
-     nsVoidArray mNativesToReleaseArray;
-     JSBool mMainThreadOnlyGC;
--    JSBool mDeferReleases;
-     JSBool mDoingFinalization;
-     XPCRootSetElem *mVariantRoots;
-     XPCRootSetElem *mWrappedJSRoots;
-@@ -1115,6 +1105,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);
-@@ -1123,28 +1119,11 @@ public:
-     SystemIsBeingShutDown(JSContext* cx);
- 
-     static void
--    SuspectAllWrappers(XPCJSRuntime* rt);
--
--    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);
- 
-@@ -1154,13 +1133,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; }
- 
- #ifndef XPCONNECT_STANDALONE
-     /**
-@@ -1173,13 +1149,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;
-@@ -1316,7 +1289,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];}
- 
-@@ -1326,17 +1299,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,
-@@ -1422,7 +1388,7 @@ private:
- /***************************************************************************/
- // XPCNativeSet represents an ordered collection of XPCNativeInterface pointers.
- 
--class XPCNativeSet
-+class XPCNativeSet : XPCOMGCObject
- {
- public:
-     static XPCNativeSet* GetNewOrUsed(XPCCallContext& ccx, const nsIID* iid);
-@@ -1467,12 +1433,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:
-@@ -1480,13 +1440,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,
-@@ -1495,9 +1449,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;
-@@ -1768,29 +1720,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:
-@@ -1827,6 +1756,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:
-@@ -1843,18 +1775,6 @@ public:
-     void SetJSObject(JSObject*  JSObj);
- 
-     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
-@@ -1867,6 +1787,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
- 
-@@ -1894,6 +1823,10 @@ private:
- private:
-     XPCWrappedNativeTearOffChunk() : mNextChunk(nsnull) {}
-     ~XPCWrappedNativeTearOffChunk() {delete mNextChunk;}
-+
-+    static void* operator new(size_t size) {
-+        return XPCOMGCObject::operator new(size);
-+    }
- 
- private:
-     XPCWrappedNativeTearOff mTearOffs[XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK];
-@@ -2065,21 +1998,9 @@ public:
-                                          XPCNativeInterface* aInterface,
-                                          JSBool needJSObject = JS_FALSE,
-                                          nsresult* pError = nsnull);
--    void Mark() const
--    {
--        mSet->Mark();
--        if(mScriptableInfo) mScriptableInfo->Mark();
--        if(HasProto()) mMaybeProto->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()) mMaybeProto->TraceJS(trc);
--        if(mWrapper)
--            JS_CALL_OBJECT_TRACER(trc, mWrapper, "XPCWrappedNative::mWrapper");
-         TraceOtherWrapper(trc);
-     }
- 
-@@ -2098,16 +2019,10 @@ public:
-     }
- 
- #ifdef DEBUG
--    void ASSERT_SetsNotMarked() const
--        {mSet->ASSERT_NotMarked();
--         if(HasProto()){mMaybeProto->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,
-@@ -3513,11 +3428,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_)                    \
-@@ -3572,9 +3482,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
-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
-@@ -297,19 +297,8 @@ nsXPCWrappedJS::~nsXPCWrappedJS()
- 
-     if(IsValid())
-     {
--        NS_IF_RELEASE(mClass);
--        if (mOuter)
--        {
--            if (rt && rt->GetThreadRunningGC())
--            {
--                rt->DeferredRelease(mOuter);
--                mOuter = nsnull;
--            }
--            else
--            {
--                NS_RELEASE(mOuter);
--            }
--        }
-+        mClass = nsnull;
-+        mOuter = nsnull;
-     }
- }
- 
-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)
-@@ -407,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;
-     }
-@@ -447,8 +442,6 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
- 
-     if(wrapperToKill)
-     {
--        // Second reference will be released by the FlatJSObject's finializer.
--        wrapperToKill->Release();
-     }
-     else if(wrapper)
-     {
-@@ -466,7 +459,6 @@ XPCWrappedNative::GetNewOrUsed(XPCCallCo
-                     map->Remove(wrapper);
-                 }
- 
--                wrapper->Release();
-                 return rv;
-             }
-         }
-@@ -569,31 +561,17 @@ XPCWrappedNative::~XPCWrappedNative()
- {
-     DEBUG_TrackDeleteWrapper(this);
- 
--    XPCWrappedNativeProto* proto = GetProto();
--
--    Native2WrappedNativeMap* map = GetScope()->GetWrappedNativeMap();
--    {   // scoped lock
--        XPCAutoLock lock(GetRuntime()->GetMapLock());
--        map->Remove(this);
--    }
--
--    if(mIdentity)
--    {
--        XPCJSRuntime* rt = GetRuntime();
--        if(rt && rt->GetDeferReleases() && 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);
--        }
--    }
-+#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
-+
-+    mIdentity = nsnull;
- }
- 
- // This is factored out so that it can be called publicly 
-@@ -910,31 +888,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 && rt->GetDeferReleases())
--                {
--                    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);
-         }
-     }
-@@ -944,17 +898,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
-@@ -1059,8 +1004,8 @@ XPCWrappedNative::ReparentWrapperIfFound
-     {
-         // Oh, so now we need to move the wrapper to a different scope.
- 
--        AutoMarkingWrappedNativeProtoPtr oldProto(ccx);
--        AutoMarkingWrappedNativeProtoPtr newProto(ccx);
-+        XPCWrappedNativeProto* oldProto = nsnull;
-+        XPCWrappedNativeProto* newProto = nsnull;
- 
-         if(wrapper->HasProto())
-         {
-@@ -1308,7 +1253,7 @@ XPCWrappedNative::ExtendSet(XPCCallConte
- 
-     if(!mSet->HasInterface(aInterface))
-     {
--        AutoMarkingNativeSetPtr newSet(ccx);
-+        XPCNativeSet* newSet;
-         newSet = XPCNativeSet::GetNewOrUsed(ccx, mSet, aInterface,
-                                             mSet->GetInterfaceCount());
-         if(!newSet)
-@@ -1379,13 +1324,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;
-                 }
-@@ -1413,12 +1356,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;
-     }
-@@ -2409,8 +2347,6 @@ done:
-             }
-             else if(dp->IsValAllocated())
-                 nsMemory::Free(p);
--            else if(dp->IsValInterface())
--                ((nsISupports*)p)->Release();
-             else if(dp->IsValDOMString())
-                 delete (nsAString*)p;
-             else if(dp->IsValUTF8String())
-@@ -2529,8 +2465,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();
- 
-@@ -2546,7 +2482,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
-@@ -213,7 +213,7 @@ XPCNativeInterface*
- XPCNativeInterface*
- XPCNativeInterface::GetNewOrUsed(XPCCallContext& ccx, const nsIID* iid)
- {
--    AutoMarkingNativeInterfacePtr iface(ccx);
-+    XPCNativeInterface* iface;
-     XPCJSRuntime* rt = ccx.GetRuntime();
- 
-     IID2NativeInterfaceMap* map = rt->GetIID2NativeInterfaceMap();
-@@ -243,12 +243,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;
-         }
-     }
-@@ -260,7 +258,7 @@ XPCNativeInterface*
- XPCNativeInterface*
- XPCNativeInterface::GetNewOrUsed(XPCCallContext& ccx, nsIInterfaceInfo* info)
- {
--    AutoMarkingNativeInterfacePtr iface(ccx);
-+    XPCNativeInterface* iface;
- 
-     const nsIID* iid;
-     if(NS_FAILED(info->GetIIDShared(&iid)) || !iid)
-@@ -290,12 +288,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;
-         }
-     }
-@@ -489,14 +485,6 @@ XPCNativeInterface::NewInstance(XPCCallC
-     return obj;
- }
- 
--// static
--void
--XPCNativeInterface::DestroyInstance(JSContext* cx, XPCJSRuntime* rt,
--                                    XPCNativeInterface* inst)
--{
--    delete inst;
--}
--
- const char*
- XPCNativeInterface::GetMemberName(XPCCallContext& ccx,
-                                   const XPCNativeMember* member) const
-@@ -525,9 +513,9 @@ XPCNativeSet*
- XPCNativeSet*
- XPCNativeSet::GetNewOrUsed(XPCCallContext& ccx, const nsIID* iid)
- {
--    AutoMarkingNativeSetPtr set(ccx);
--
--    AutoMarkingNativeInterfacePtr iface(ccx);
-+    XPCNativeSet* set = nsnull;
-+
-+    XPCNativeInterface* iface;
-     iface = XPCNativeInterface::GetNewOrUsed(ccx, iid);
-     if(!iface)
-         return nsnull;
-@@ -559,12 +547,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;
-         }
-     }
-@@ -576,7 +562,7 @@ XPCNativeSet*
- XPCNativeSet*
- XPCNativeSet::GetNewOrUsed(XPCCallContext& ccx, nsIClassInfo* classInfo)
- {
--    AutoMarkingNativeSetPtr set(ccx);
-+    XPCNativeSet* set = nsnull;
-     XPCJSRuntime* rt = ccx.GetRuntime();
- 
-     ClassInfo2NativeSetMap* map = rt->GetClassInfo2NativeSetMap();
-@@ -592,7 +578,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)))
-@@ -612,12 +599,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;
-@@ -661,13 +648,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;
-                     }
-                 }
-@@ -691,7 +676,7 @@ out:
-     if(iidArray)
-         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(iidCount, iidArray);
-     if(interfaceArray)
--        delete [] interfaceArray.get();
-+        NS_GetGC()->Free(interfaceArray);
- 
-     return set;
- }
-@@ -718,7 +703,7 @@ XPCNativeSet::GetNewOrUsed(XPCCallContex
-                            XPCNativeInterface* newInterface,
-                            PRUint16 position)
- {
--    AutoMarkingNativeSetPtr set(ccx);
-+    XPCNativeSet* set;
-     XPCJSRuntime* rt = ccx.GetRuntime();
-     NativeSetMap* map = rt->GetNativeSetMap();
-     if(!map)
-@@ -748,12 +733,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;
-         }
-     }
-@@ -789,14 +772,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)
-     {
-@@ -838,12 +814,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)
-     {
-@@ -874,12 +849,15 @@ XPCNativeSet::NewInstanceMutate(XPCNativ
-     return obj;
- }
- 
--// static
--void
--XPCNativeSet::DestroyInstance(XPCNativeSet* inst)
--{
--    inst->~XPCNativeSet();
--    delete [] (char*) inst;
-+void*
-+XPCNativeSet::operator new(size_t size, PRUint16 interfaceCount)
-+{
-+    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;
- 
-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
-@@ -177,7 +177,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;
-@@ -216,7 +216,7 @@ XPCWrappedNativeProto::GetNewOrUsed(XPCC
-         }
-     }
- 
--    AutoMarkingNativeSetPtr set(ccx);
-+    XPCNativeSet* set;
-     set = XPCNativeSet::GetNewOrUsed(ccx, ClassInfo);
-     if(!set)
-         return nsnull;
-@@ -225,7 +225,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
-@@ -107,7 +107,6 @@ static void DEBUG_TrackScopeShutdown()
- /***************************************************************************/
- 
- XPCWrappedNativeScope* XPCWrappedNativeScope::gScopes = nsnull;
--XPCWrappedNativeScope* XPCWrappedNativeScope::gDyingScopes = nsnull;
- 
- // static
- XPCWrappedNativeScope*
-@@ -159,18 +158,6 @@ XPCWrappedNativeScope::XPCWrappedNativeS
- 
-     DEBUG_TrackNewScope(this);
-     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
-@@ -255,6 +242,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");
-@@ -277,167 +271,40 @@ XPCWrappedNativeScope::~XPCWrappedNative
-     NS_IF_RELEASE(mComponents);
- }
- 
-+
-+
-+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());
--
--    // 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)
--    {
--        XPCWrappedNativeScope* next = cur->mNext;
--        if(cur->mGlobalJSObject &&
--           JS_IsAboutToBeFinalized(cx, cur->mGlobalJSObject))
--        {
--            cur->mGlobalJSObject = nsnull;
--
--            // Move this scope from the live list to the dying list.
-+
-+    for(XPCWrappedNativeScope *cur = gScopes;
-+        cur;
-+        prev = cur, cur = cur->mNext)
-+    {
-+        if(NS_GetGC()->GetMark(cur))
-+        {
-+            // If the scope is marked, regulate its maps
-+            cur->UnmapDyingNatives();
-+        }
-+        else
-+        {
-+            // If the scope is not marked, remove it from our linked list
-             if(prev)
--                prev->mNext = next;
-+                prev->mNext = cur->mNext;
-             else
--                gScopes = next;
--            cur->mNext = gDyingScopes;
--            gDyingScopes = cur;
--            cur = nsnull;
--        }
--        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)
--            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;
-+                gScopes = cur->mNext;
-+        }
-+    }
- }
- 
- struct ShutdownData
-@@ -486,28 +353,15 @@ XPCWrappedNativeScope::SystemIsBeingShut
-     DEBUG_TrackScopeTraversal();
-     DEBUG_TrackScopeShutdown();
- 
--    int liveScopeCount = 0;
--
-     ShutdownData data(cx);
- 
--    XPCWrappedNativeScope* cur;
--
--    // 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++;
--    }
-+    XPCWrappedNativeScope* cur = gScopes;
-+
-     gScopes = nsnull;
- 
--    // Walk the unified dying list and call shutdown on all wrappers and protos
--
--    for(cur = gDyingScopes; cur; cur = cur->mNext)
-+    // Walk the list of scopes and call shutdown on all wrappers and protos
-+
-+    for(; cur; cur = cur->mNext)
-     {
-         // Give the Components object a chance to try to clean up.
-         if(cur->mComponents)
-@@ -520,9 +374,6 @@ XPCWrappedNativeScope::SystemIsBeingShut
-         cur->mWrappedNativeMap->
-                 Enumerate(WrappedNativeShutdownEnumerator,  &data);
-     }
--
--    // Now it is safe to kill all the scopes.
--    KillDyingScopes();
- 
- #ifdef XPC_DUMP_AT_SHUTDOWN
-     if(data.wrapperCount)
-@@ -532,9 +383,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
- }
- 
-@@ -726,7 +574,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);