root-contentutils
author Benjamin Smedberg <benjamin@smedbergs.us>
Sat, 26 Jul 2008 22:49:39 -0400
changeset 167 a4da40849f5436e629c5732f4368c6c48189637f
parent 153 cd96178a2e472dc6cd10443a56a3cedf9e8e1140
permissions -rw-r--r--
State as of now

Root objects that hang off contentutils in one easy object.
* * *
* * *

diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -137,6 +137,8 @@ struct nsShortcutCandidate {
 
 class nsContentUtils
 {
+  struct LayoutRoots;
+
 public:
   static nsresult Init();
 
@@ -454,17 +456,17 @@ public:
 
   static nsINameSpaceManager* NameSpaceManager()
   {
-    return sNameSpaceManager;
+    return sLayoutRoots->sNameSpaceManager;
   }
 
   static nsIIOService* GetIOService()
   {
-    return sIOService;
+    return sLayoutRoots->sIOService;
   }
 
   static imgILoader* GetImgLoader()
   {
-    return sImgLoader;
+    return sLayoutRoots->sImgLoader;
   }
 
 #ifdef MOZ_XTF
@@ -481,7 +483,7 @@ public:
    */
   static nsIScriptSecurityManager* GetSecurityManager()
   {
-    return sSecurityManager;
+    return sLayoutRoots->sSecurityManager;
   }
 
   static nsresult GenerateStateKey(nsIContent* aContent,
@@ -566,27 +568,27 @@ public:
   static void AddBoolPrefVarCache(const char* aPref, PRBool* aVariable);
   static nsIPrefBranch *GetPrefBranch()
   {
-    return sPrefBranch;
+    return sLayoutRoots->sPrefBranch;
   }
 
   static nsILineBreaker* LineBreaker()
   {
-    return sLineBreaker;
+    return sLayoutRoots->sLineBreaker;
   }
 
   static nsIWordBreaker* WordBreaker()
   {
-    return sWordBreaker;
+    return sLayoutRoots->sWordBreaker;
   }
   
   static nsICaseConversion* GetCaseConv()
   {
-    return sCaseConv;
+    return sLayoutRoots->sCaseConv;
   }
 
   static nsIUGenCategory* GetGenCat()
   {
-    return sGenCat;
+    return sLayoutRoots->sGenCat;
   }
 
   /**
@@ -654,7 +656,7 @@ public:
    * @param aRequest The image request [out]
    * @return the nsIImage corresponding to the first frame of the image
    */
-  static already_AddRefed<nsIImage> GetImageFromContent(nsIImageLoadingContent* aContent, imgIRequest **aRequest = nsnull);
+  static nsIImage* GetImageFromContent(nsIImageLoadingContent* aContent, imgIRequest **aRequest = nsnull);
 
   /**
    * Method that decides whether a content node is draggable
@@ -738,7 +740,7 @@ public:
    */
   static nsIXPConnect *XPConnect()
   {
-    return sXPConnect;
+    return sLayoutRoots->sXPConnect;
   }
 
   /**
@@ -811,11 +813,10 @@ public:
   /**
    * Release *aSupportsPtr when the shutdown notification is received
    */
-  static nsresult ReleasePtrOnShutdown(nsISupports** aSupportsPtr) {
-    NS_ASSERTION(aSupportsPtr, "Expect to crash!");
-    NS_ASSERTION(*aSupportsPtr, "Expect to crash!");
-    return sPtrsToPtrsToRelease->AppendElement(aSupportsPtr) ? NS_OK :
-      NS_ERROR_OUT_OF_MEMORY;
+  static nsresult RootUntilLayoutShutdown(void *aSupportsPtr) {
+    NS_ASSERTION(aSupportsPtr, "Useless call");
+    return sLayoutRoots->sExtraLayoutRoots.
+      AppendElement(aSupportsPtr) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
   }
 
   /**
@@ -901,7 +902,7 @@ public:
 
   static PRBool IsInitialized()
   {
-    return sInitialized;
+    return sLayoutRoots != nsnull;
   }
 
   /**
@@ -1161,6 +1162,10 @@ public:
    */
   static PRBool OfflineAppAllowed(nsIURI *aURI);
 
+  static JSRuntime *GetJSScriptRuntime();
+  static nsresult AddJSGCRoot(void *aPtr, const char* aName);
+  static nsresult RemoveJSGCRoot(void *aPtr);
+
   /**
    * Increases the count of blockers preventing scripts from running.
    * NOTE: You might want to use nsAutoScriptBlocker rather than calling
@@ -1225,8 +1230,6 @@ public:
 
 private:
 
-  static PRBool InitializeEventTable();
-
   static nsresult doReparentContentWrapper(nsIContent *aChild,
                                            JSContext *cx,
                                            JSObject *aOldGlobal,
@@ -1245,60 +1248,69 @@ private:
   static PRBool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
                                 nsIPrincipal* aPrincipal);
 
-  static nsIDOMScriptObjectFactory *sDOMScriptObjectFactory;
+  struct LayoutRoots : public MMgc::GCRoot
+  {
+    LayoutRoots() :
+      MMgc::GCRoot(NS_GetGC()) { }
 
-  static nsIXPConnect *sXPConnect;
+    static void* operator new(size_t size) {
+      void *p = MMgc::FixedMalloc::GetInstance()->Alloc(size);
+      memset(p, 0, size);
+      return p;
+    }
 
-  static nsIScriptSecurityManager *sSecurityManager;
+    nsresult Init();
 
-  static nsIThreadJSContextStack *sThreadJSContextStack;
+    PRBool InitializeEventTable();
 
-  static nsIParserService *sParserService;
+    nsIDOMScriptObjectFactory *sDOMScriptObjectFactory;
+    nsIXPConnect *sXPConnect;
+    nsIScriptSecurityManager *sSecurityManager;
+    nsIThreadJSContextStack *sThreadJSContextStack;
+    nsIParserService *sParserService;
+    nsINameSpaceManager *sNameSpaceManager;
+    nsIIOService *sIOService;
+#ifdef MOZ_XTF
+    nsIXTFService *sXTFService;
+#endif
+    nsIPrefBranch *sPrefBranch;
+    nsIPref *sPref;
+    imgILoader* sImgLoader;
+    nsIConsoleService* sConsoleService;
+    nsDataHashtable<nsISupportsHashKey, EventNameMapping, GCAllocator> sEventTable;
+    nsIStringBundleService* sStringBundleService;
+    nsIStringBundle* sStringBundles[PropertiesFile_COUNT];
+    nsIContentPolicy* sContentPolicyService;
 
-  static nsINameSpaceManager *sNameSpaceManager;
+    nsILineBreaker* sLineBreaker;
+    nsIWordBreaker* sWordBreaker;
+    nsICaseConversion* sCaseConv;
+    nsIUGenCategory* sGenCat;
 
-  static nsIIOService *sIOService;
+    // Holds pointers to nsISupports* that should be released at shutdown
+    nsVoidArrayBase<GCAllocator> sExtraLayoutRoots;
 
-#ifdef MOZ_XTF
-  static nsIXTFService *sXTFService;
+    nsIScriptRuntime* sScriptRuntimes[NS_STID_ARRAY_UBOUND];
+
+#ifdef IBMBIDI
+    nsIBidiKeyboard* sBidiKeyboard;
 #endif
 
-  static nsIPrefBranch *sPrefBranch;
+    nsIJSRuntimeService* sJSRuntimeService;
+    JSRuntime* sJSScriptRuntime;
 
-  static nsIPref *sPref;
+    nsCOMArray<nsIRunnable> sBlockedScriptRunners;
+  };
 
-  static imgILoader* sImgLoader;
+  static LayoutRoots *sLayoutRoots;
 
-  static nsIConsoleService* sConsoleService;
-
-  static nsDataHashtable<nsISupportsHashKey, EventNameMapping, GCAllocator>* sEventTable;
-
-  static nsIStringBundleService* sStringBundleService;
-  static nsIStringBundle* sStringBundles[PropertiesFile_COUNT];
-
-  static nsIContentPolicy* sContentPolicyService;
-  static PRBool sTriedToGetContentPolicy;
-
-  static nsILineBreaker* sLineBreaker;
-  static nsIWordBreaker* sWordBreaker;
-  static nsICaseConversion* sCaseConv;
-  static nsIUGenCategory* sGenCat;
-
-  // Holds pointers to nsISupports* that should be released at shutdown
-  static nsVoidArray* sPtrsToPtrsToRelease;
-
-  static nsIScriptRuntime* sScriptRuntimes[NS_STID_ARRAY_UBOUND];
   static PRInt32 sScriptRootCount[NS_STID_ARRAY_UBOUND];
   static PRUint32 sJSGCThingRootCount;
 
-#ifdef IBMBIDI
-  static nsIBidiKeyboard* sBidiKeyboard;
-#endif
+  static PRBool sTriedToGetContentPolicy;
 
-  static PRBool sInitialized;
   static PRUint32 sScriptBlockerCount;
   static PRUint32 sRemovableScriptBlockerCount;
-  static nsCOMArray<nsIRunnable>* sBlockedScriptRunners;
   static PRUint32 sRunnersCountAtFirstBlocker;
 };
 
@@ -1328,37 +1340,30 @@ public:
   nsAutoGCRoot(jsval* aPtr, nsresult* aResult) :
     mPtr(aPtr)
   {
-    mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot");
+    mResult = *aResult = nsContentUtils::AddJSGCRoot(aPtr, "nsAutoGCRoot");
   }
 
   // aPtr should be the pointer to the JSObject* we want to protect
   nsAutoGCRoot(JSObject** aPtr, nsresult* aResult) :
     mPtr(aPtr)
   {
-    mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot");
+    mResult = *aResult = nsContentUtils::AddJSGCRoot(aPtr, "nsAutoGCRoot");
   }
 
   // aPtr should be the pointer to the thing we want to protect
   nsAutoGCRoot(void* aPtr, nsresult* aResult) :
     mPtr(aPtr)
   {
-    mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot");
+    mResult = *aResult = nsContentUtils::AddJSGCRoot(aPtr, "nsAutoGCRoot");
   }
 
   ~nsAutoGCRoot() {
     if (NS_SUCCEEDED(mResult)) {
-      RemoveJSGCRoot(mPtr);
+      nsContentUtils::RemoveJSGCRoot(mPtr);
     }
   }
 
-  static void Shutdown();
-
 private:
-  static nsresult AddJSGCRoot(void *aPtr, const char* aName);
-  static nsresult RemoveJSGCRoot(void *aPtr);
-
-  static nsIJSRuntimeService* sJSRuntimeService;
-  static JSRuntime* sJSScriptRuntime;
 
   void* mPtr;
   nsresult mResult;
diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -174,45 +174,12 @@ static NS_DEFINE_CID(kParserServiceCID, 
 static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
 static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
 
-nsIDOMScriptObjectFactory *nsContentUtils::sDOMScriptObjectFactory = nsnull;
-nsIXPConnect *nsContentUtils::sXPConnect;
-nsIScriptSecurityManager *nsContentUtils::sSecurityManager;
-nsIThreadJSContextStack *nsContentUtils::sThreadJSContextStack;
-nsIParserService *nsContentUtils::sParserService = nsnull;
-nsINameSpaceManager *nsContentUtils::sNameSpaceManager;
-nsIIOService *nsContentUtils::sIOService;
-#ifdef MOZ_XTF
-nsIXTFService *nsContentUtils::sXTFService = nsnull;
-#endif
-nsIPrefBranch *nsContentUtils::sPrefBranch = nsnull;
-nsIPref *nsContentUtils::sPref = nsnull;
-imgILoader *nsContentUtils::sImgLoader;
-nsIConsoleService *nsContentUtils::sConsoleService;
-nsDataHashtable<nsISupportsHashKey, EventNameMapping, GCAllocator>* nsContentUtils::sEventTable = nsnull;
-nsIStringBundleService *nsContentUtils::sStringBundleService;
-nsIStringBundle *nsContentUtils::sStringBundles[PropertiesFile_COUNT];
-nsIContentPolicy *nsContentUtils::sContentPolicyService;
-PRBool nsContentUtils::sTriedToGetContentPolicy = PR_FALSE;
-nsILineBreaker *nsContentUtils::sLineBreaker;
-nsIWordBreaker *nsContentUtils::sWordBreaker;
-nsICaseConversion *nsContentUtils::sCaseConv;
-nsIUGenCategory *nsContentUtils::sGenCat;
-nsVoidArray *nsContentUtils::sPtrsToPtrsToRelease;
-nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND];
+nsContentUtils::LayoutRoots* nsContentUtils::sLayoutRoots;
 PRInt32 nsContentUtils::sScriptRootCount[NS_STID_ARRAY_UBOUND];
-PRUint32 nsContentUtils::sJSGCThingRootCount;
-#ifdef IBMBIDI
-nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull;
-#endif
-PRUint32 nsContentUtils::sScriptBlockerCount = 0;
-PRUint32 nsContentUtils::sRemovableScriptBlockerCount = 0;
-nsCOMArray<nsIRunnable>* nsContentUtils::sBlockedScriptRunners = nsnull;
-PRUint32 nsContentUtils::sRunnersCountAtFirstBlocker = 0;
-
-nsIJSRuntimeService *nsAutoGCRoot::sJSRuntimeService;
-JSRuntime *nsAutoGCRoot::sJSScriptRuntime;
-
-PRBool nsContentUtils::sInitialized = PR_FALSE;
+PRBool nsContentUtils::sTriedToGetContentPolicy;
+PRUint32 nsContentUtils::sScriptBlockerCount;
+PRUint32 nsContentUtils::sRemovableScriptBlockerCount;
+PRUint32 nsContentUtils::sRunnersCountAtFirstBlocker;
 
 static PLDHashTable sEventListenerManagersHash;
 
@@ -259,20 +226,31 @@ nsresult
 nsresult
 nsContentUtils::Init()
 {
-  if (sInitialized) {
-    NS_WARNING("Init() called twice");
-
-    return NS_OK;
-  }
-
+  NS_ASSERTION(!sLayoutRoots, "nsContentUtils::Init called twice");
+
+  LayoutRoots *roots = new LayoutRoots();
+  nsresult rv = roots->Init();
+  if (NS_FAILED(rv)) {
+    delete roots;
+    return rv;
+  }
+  sLayoutRoots = roots;
+  return NS_OK;
+}
+
+nsresult
+nsContentUtils::LayoutRoots::Init()
+{
   nsresult rv = CallGetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID,
                                &sSecurityManager);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // It's ok to not have a pref service.
+  sPrefBranch = nsnull;
   CallGetService(NS_PREFSERVICE_CONTRACTID, &sPrefBranch);
 
   // It's ok to not have prefs too.
+  sPref = nsnull;
   CallGetService(NS_PREF_CONTRACTID, &sPref);
 
   rv = NS_GetNameSpaceManager(&sNameSpaceManager);
@@ -284,12 +262,8 @@ nsContentUtils::Init()
   rv = CallGetService(kJSStackContractID, &sThreadJSContextStack);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  sIOService = nsnull;
   rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService);
-  if (NS_FAILED(rv)) {
-    // This makes life easier, but we can live without it.
-
-    sIOService = nsnull;
-  }
 
   rv = CallGetService(NS_LBRK_CONTRACTID, &sLineBreaker);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -304,16 +278,8 @@ nsContentUtils::Init()
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Ignore failure and just don't load images
+  sImgLoader = nsnull;
   rv = CallGetService("@mozilla.org/image/loader;1", &sImgLoader);
-  if (NS_FAILED(rv)) {
-    // no image loading for us.  Oh, well.
-    sImgLoader = nsnull;
-  }
-
-  sPtrsToPtrsToRelease = new nsVoidArray();
-  if (!sPtrsToPtrsToRelease) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
 
   if (!InitializeEventTable())
     return NS_ERROR_FAILURE;
@@ -339,18 +305,11 @@ nsContentUtils::Init()
     }
   }
 
-  sBlockedScriptRunners = new nsCOMArray<nsIRunnable>;
-  NS_ENSURE_TRUE(sBlockedScriptRunners, NS_ERROR_OUT_OF_MEMORY);
-
-  sInitialized = PR_TRUE;
-
-  return NS_OK;
-}
-
-PRBool
-nsContentUtils::InitializeEventTable() {
-  NS_ASSERTION(!sEventTable, "EventTable already initialized!");
-
+  return NS_OK;
+}
+
+PRBool
+nsContentUtils::LayoutRoots::InitializeEventTable() {
   struct EventItem
   {
     nsIAtom** mAtom;
@@ -461,21 +420,12 @@ nsContentUtils::InitializeEventTable() {
 #endif //MOZ_MEDIA
   };
 
-  sEventTable = new nsDataHashtable<nsISupportsHashKey, EventNameMapping, GCAllocator>;
-  if (!sEventTable ||
-      !sEventTable->Init(int(NS_ARRAY_LENGTH(eventArray) / 0.75) + 1)) {
-    delete sEventTable;
-    sEventTable = nsnull;
-    return PR_FALSE;
-  }
-
-  for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(eventArray); ++i) {
-    if (!sEventTable->Put(*(eventArray[i].mAtom), eventArray[i].mValue)) {
-      delete sEventTable;
-      sEventTable = nsnull;
+  if (!sEventTable.Init(int(NS_ARRAY_LENGTH(eventArray) / 0.75) + 1))
+    return PR_FALSE;
+
+  for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(eventArray); ++i)
+    if (!sEventTable.Put(*(eventArray[i].mAtom), eventArray[i].mValue))
       return PR_FALSE;
-    }
-  }
 
   return PR_TRUE;
 }
@@ -489,30 +439,30 @@ nsContentUtils::GetParserService()
 nsContentUtils::GetParserService()
 {
   // XXX: This isn't accessed from several threads, is it?
-  if (!sParserService) {
+  if (!sLayoutRoots->sParserService) {
     // Lock, recheck sCachedParserService and aquire if this should be
     // safe for multiple threads.
-    nsresult rv = CallGetService(kParserServiceCID, &sParserService);
-    if (NS_FAILED(rv)) {
-      sParserService = nsnull;
-    }
-  }
-
-  return sParserService;
+    nsresult rv = CallGetService(kParserServiceCID, &sLayoutRoots->sParserService);
+    if (NS_FAILED(rv)) {
+      sLayoutRoots->sParserService = nsnull;
+    }
+  }
+
+  return sLayoutRoots->sParserService;
 }
 
 #ifdef MOZ_XTF
 nsIXTFService*
 nsContentUtils::GetXTFService()
 {
-  if (!sXTFService) {
-    nsresult rv = CallGetService(kXTFServiceCID, &sXTFService);
-    if (NS_FAILED(rv)) {
-      sXTFService = nsnull;
-    }
-  }
-
-  return sXTFService;
+  if (!sLayoutRoots->sXTFService) {
+    nsresult rv = CallGetService(kXTFServiceCID, &sLayoutRoots->sXTFService);
+    if (NS_FAILED(rv)) {
+      sLayoutRoots->sXTFService = nsnull;
+    }
+  }
+
+  return sLayoutRoots->sXTFService;
 }
 #endif
 
@@ -520,13 +470,13 @@ nsIBidiKeyboard*
 nsIBidiKeyboard*
 nsContentUtils::GetBidiKeyboard()
 {
-  if (!sBidiKeyboard) {
-    nsresult rv = CallGetService("@mozilla.org/widget/bidikeyboard;1", &sBidiKeyboard);
-    if (NS_FAILED(rv)) {
-      sBidiKeyboard = nsnull;
-    }
-  }
-  return sBidiKeyboard;
+  if (!sLayoutRoots->sBidiKeyboard) {
+    nsresult rv = CallGetService("@mozilla.org/widget/bidikeyboard;1", &sLayoutRoots->sBidiKeyboard);
+    if (NS_FAILED(rv)) {
+      sLayoutRoots->sBidiKeyboard = nsnull;
+    }
+  }
+  return sLayoutRoots->sBidiKeyboard;
 }
 #endif
 
@@ -733,7 +683,7 @@ nsContentUtils::IsPunctuationMarkAt(cons
 // static
 PRBool nsContentUtils::IsAlphanumeric(PRUint32 aChar)
 {
-  nsIUGenCategory::nsUGenCategory cat = sGenCat->Get(aChar);
+  nsIUGenCategory::nsUGenCategory cat = sLayoutRoots->sGenCat->Get(aChar);
 
   return (cat == nsIUGenCategory::kLetter || cat == nsIUGenCategory::kNumber);
 }
@@ -846,52 +796,13 @@ void
 void
 nsContentUtils::Shutdown()
 {
-  sInitialized = PR_FALSE;
+  LayoutRoots *roots = sLayoutRoots;
+  sLayoutRoots = nsnull;
 
   NS_HTMLParanoidFragmentSinkShutdown();
   NS_XHTMLParanoidFragmentSinkShutdown();
 
-  NS_IF_RELEASE(sContentPolicyService);
   sTriedToGetContentPolicy = PR_FALSE;
-  PRInt32 i;
-  for (i = 0; i < PRInt32(PropertiesFile_COUNT); ++i)
-    NS_IF_RELEASE(sStringBundles[i]);
-  NS_IF_RELEASE(sStringBundleService);
-  NS_IF_RELEASE(sConsoleService);
-  NS_IF_RELEASE(sDOMScriptObjectFactory);
-  if (sJSGCThingRootCount == 0 && sXPConnect)
-    NS_RELEASE(sXPConnect);
-  NS_IF_RELEASE(sSecurityManager);
-  NS_IF_RELEASE(sThreadJSContextStack);
-  NS_IF_RELEASE(sNameSpaceManager);
-  NS_IF_RELEASE(sParserService);
-  NS_IF_RELEASE(sIOService);
-  NS_IF_RELEASE(sLineBreaker);
-  NS_IF_RELEASE(sWordBreaker);
-  NS_IF_RELEASE(sCaseConv);
-  NS_IF_RELEASE(sGenCat);
-#ifdef MOZ_XTF
-  NS_IF_RELEASE(sXTFService);
-#endif
-  NS_IF_RELEASE(sImgLoader);
-  NS_IF_RELEASE(sPrefBranch);
-  NS_IF_RELEASE(sPref);
-#ifdef IBMBIDI
-  NS_IF_RELEASE(sBidiKeyboard);
-#endif
-
-  delete sEventTable;
-  sEventTable = nsnull;
-
-  if (sPtrsToPtrsToRelease) {
-    for (i = 0; i < sPtrsToPtrsToRelease->Count(); ++i) {
-      nsISupports** ptrToPtr =
-        static_cast<nsISupports**>(sPtrsToPtrsToRelease->ElementAt(i));
-      NS_RELEASE(*ptrToPtr);
-    }
-    delete sPtrsToPtrsToRelease;
-    sPtrsToPtrsToRelease = nsnull;
-  }
 
   if (sEventListenerManagersHash.ops) {
     NS_ASSERTION(sEventListenerManagersHash.entryCount == 0,
@@ -912,13 +823,10 @@ nsContentUtils::Shutdown()
     }
   }
 
-  NS_ASSERTION(!sBlockedScriptRunners ||
-               sBlockedScriptRunners->Count() == 0,
+  NS_ASSERTION(roots->sBlockedScriptRunners.Count() == 0,
                "How'd this happen?");
-  delete sBlockedScriptRunners;
-  sBlockedScriptRunners = nsnull;
-
-  nsAutoGCRoot::Shutdown();
+
+  delete roots;
 }
 
 // static
@@ -928,12 +836,12 @@ nsContentUtils::IsCallerTrustedForCapabi
   // The secman really should handle UniversalXPConnect case, since that
   // should include UniversalBrowserRead... doesn't right now, though.
   PRBool hasCap;
-  if (NS_FAILED(sSecurityManager->IsCapabilityEnabled(aCapability, &hasCap)))
+  if (NS_FAILED(sLayoutRoots->sSecurityManager->IsCapabilityEnabled(aCapability, &hasCap)))
     return PR_FALSE;
   if (hasCap)
     return PR_TRUE;
     
-  if (NS_FAILED(sSecurityManager->IsCapabilityEnabled("UniversalXPConnect",
+  if (NS_FAILED(sLayoutRoots->sSecurityManager->IsCapabilityEnabled("UniversalXPConnect",
                                                       &hasCap)))
     return PR_FALSE;
   return hasCap;
@@ -954,7 +862,7 @@ nsContentUtils::CheckSameOrigin(nsIDOMNo
   NS_PRECONDITION(aTrustedNode, "There must be a trusted node");
 
   PRBool isSystem = PR_FALSE;
-  sSecurityManager->SubjectPrincipalIsSystem(&isSystem);
+  sLayoutRoots->sSecurityManager->SubjectPrincipalIsSystem(&isSystem);
   if (isSystem) {
     // we're running as system, grant access to the node.
 
@@ -964,8 +872,8 @@ nsContentUtils::CheckSameOrigin(nsIDOMNo
   /*
    * Get hold of each node's principal
    */
-  nsCOMPtr<nsINode> trustedNode = do_QueryInterface(aTrustedNode);
-  nsCOMPtr<nsINode> unTrustedNode = do_QueryInterface(aUnTrustedNode);
+  nsINode* trustedNode = do_QueryInterface(aTrustedNode);
+  nsINode* unTrustedNode = do_QueryInterface(aUnTrustedNode);
 
   // Make sure these are both real nodes
   NS_ENSURE_TRUE(trustedNode && unTrustedNode, NS_ERROR_UNEXPECTED);
@@ -1005,7 +913,7 @@ nsContentUtils::CanCallerAccess(nsIPrinc
   // has either "UniversalXPConnect" (if aPrincipal is system principal) or
   // "UniversalBrowserRead" (in all other cases).
   PRBool isSystem;
-  rv = sSecurityManager->IsSystemPrincipal(aPrincipal, &isSystem);
+  rv = sLayoutRoots->sSecurityManager->IsSystemPrincipal(aPrincipal, &isSystem);
   isSystem = NS_FAILED(rv) || isSystem;
   const char* capability =
     NS_FAILED(rv) || isSystem ? "UniversalXPConnect" : "UniversalBrowserRead";
@@ -1016,34 +924,34 @@ nsContentUtils::CanCallerAccess(nsIPrinc
 // static
 PRBool
 nsContentUtils::CanCallerAccess(nsIDOMNode *aNode)
+{
+  // XXXbz why not check the IsCapabilityEnabled thing up front, and not bother
+  // with the system principal games?  But really, there should be a simpler
+  // API here, dammit.
+  nsIPrincipal* subjectPrincipal = nsnull;
+  sLayoutRoots->sSecurityManager->GetSubjectPrincipal(&subjectPrincipal);
+
+  if (!subjectPrincipal) {
+    // we're running as system, grant access to the node.
+
+    return PR_TRUE;
+  }
+
+  nsINode* node = do_QueryInterface(aNode);
+  NS_ENSURE_TRUE(node, PR_FALSE);
+
+  return CanCallerAccess(subjectPrincipal, node->NodePrincipal());
+}
+
+// static
+PRBool
+nsContentUtils::CanCallerAccess(nsPIDOMWindow* aWindow)
 {
   // XXXbz why not check the IsCapabilityEnabled thing up front, and not bother
   // with the system principal games?  But really, there should be a simpler
   // API here, dammit.
   nsCOMPtr<nsIPrincipal> subjectPrincipal;
-  sSecurityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
-
-  if (!subjectPrincipal) {
-    // we're running as system, grant access to the node.
-
-    return PR_TRUE;
-  }
-
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  NS_ENSURE_TRUE(node, PR_FALSE);
-
-  return CanCallerAccess(subjectPrincipal, node->NodePrincipal());
-}
-
-// static
-PRBool
-nsContentUtils::CanCallerAccess(nsPIDOMWindow* aWindow)
-{
-  // XXXbz why not check the IsCapabilityEnabled thing up front, and not bother
-  // with the system principal games?  But really, there should be a simpler
-  // API here, dammit.
-  nsCOMPtr<nsIPrincipal> subjectPrincipal;
-  sSecurityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
+  sLayoutRoots->sSecurityManager->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
 
   if (!subjectPrincipal) {
     // we're running as system, grant access to the node.
@@ -1085,17 +993,17 @@ nsContentUtils::doReparentContentWrapper
                                          nsIDocument *aOldDocument,
                                          nsIDocument *aNewDocument)
 {
-  nsCOMPtr<nsIXPConnectJSObjectHolder> old_wrapper;
-
-  nsresult rv;
-
-  rv = sXPConnect->ReparentWrappedNativeIfFound(cx, aOldGlobal, aNewGlobal,
+  nsIXPConnectJSObjectHolder* old_wrapper = nsnull;
+
+  nsresult rv;
+
+  rv = sLayoutRoots->sXPConnect->ReparentWrappedNativeIfFound(cx, aOldGlobal, aNewGlobal,
                                                 aNode,
-                                                getter_AddRefs(old_wrapper));
+                                                &old_wrapper);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aOldDocument) {
-    nsCOMPtr<nsISupports> old_ref = aOldDocument->GetReference(aNode);
+    nsISupports* old_ref = aOldDocument->GetReference(aNode);
     if (old_ref) {
       // Transfer the reference from aOldDocument to aNewDocument
       aOldDocument->RemoveReference(aNode);
@@ -1191,7 +1099,7 @@ nsContentUtils::GetContextAndScopes(nsID
     return NS_OK;
   }
 
-  NS_ENSURE_TRUE(sXPConnect, NS_ERROR_NOT_INITIALIZED);
+  NS_ENSURE_TRUE(sLayoutRoots->sXPConnect, NS_ERROR_NOT_INITIALIZED);
 
   // Make sure to get our hands on the right scope object, since
   // GetWrappedNativeOfNativeObject doesn't call PreCreate and hence won't get
@@ -1216,10 +1124,10 @@ nsContentUtils::GetContextAndScopes(nsID
       // calling context, or the safe context if no caller can be
       // found.
 
-      sThreadJSContextStack->Peek(&cx);
+      sLayoutRoots->sThreadJSContextStack->Peek(&cx);
 
       if (!cx) {
-        sThreadJSContextStack->GetSafeJSContext(&cx);
+        sLayoutRoots->sThreadJSContextStack->GetSafeJSContext(&cx);
 
         if (!cx) {
           // No safe context reachable, bail.
@@ -1257,10 +1165,10 @@ nsContentUtils::ReparentContentWrappersI
     }
 
     if (!cx) {
-      sThreadJSContextStack->Peek(&cx);
+      sLayoutRoots->sThreadJSContextStack->Peek(&cx);
 
       if (!cx) {
-        sThreadJSContextStack->GetSafeJSContext(&cx);
+        sLayoutRoots->sThreadJSContextStack->GetSafeJSContext(&cx);
 
         if (!cx) {
           // Wow, this is really bad!
@@ -1284,18 +1192,18 @@ nsContentUtils::ReparentContentWrappersI
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  return sXPConnect->ReparentScopeAwareWrappers(cx, oldScopeObj, newScopeObj);
+  return sLayoutRoots->sXPConnect->ReparentScopeAwareWrappers(cx, oldScopeObj, newScopeObj);
 }
 
 nsIDocShell *
 nsContentUtils::GetDocShellFromCaller()
 {
   JSContext *cx = nsnull;
-  sThreadJSContextStack->Peek(&cx);
+  sLayoutRoots->sThreadJSContextStack->Peek(&cx);
 
   if (cx) {
     nsIScriptGlobalObject *sgo = nsJSUtils::GetDynamicScriptGlobal(cx);
-    nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(sgo));
+    nsPIDOMWindow* win(do_QueryInterface(sgo));
 
     if (win) {
       return win->GetDocShell();
@@ -1309,7 +1217,7 @@ nsContentUtils::GetDocumentFromCaller()
 nsContentUtils::GetDocumentFromCaller()
 {
   JSContext *cx = nsnull;
-  sThreadJSContextStack->Peek(&cx);
+  sLayoutRoots->sThreadJSContextStack->Peek(&cx);
 
   nsIDOMDocument *doc = nsnull;
 
@@ -1320,7 +1228,7 @@ nsContentUtils::GetDocumentFromCaller()
       callee = ::JS_GetFrameCalleeObject(cx, fp);
     }
 
-    nsCOMPtr<nsPIDOMWindow> win =
+    nsPIDOMWindow* win =
       do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(cx, callee));
     if (win) {
       doc = win->GetExtantDocument();
@@ -1334,13 +1242,13 @@ nsContentUtils::GetDocumentFromContext()
 nsContentUtils::GetDocumentFromContext()
 {
   JSContext *cx = nsnull;
-  sThreadJSContextStack->Peek(&cx);
+  sLayoutRoots->sThreadJSContextStack->Peek(&cx);
 
   if (cx) {
     nsIScriptGlobalObject *sgo = nsJSUtils::GetDynamicScriptGlobal(cx);
 
     if (sgo) {
-      nsCOMPtr<nsPIDOMWindow> pwin = do_QueryInterface(sgo);
+      nsPIDOMWindow* pwin = do_QueryInterface(sgo);
       if (pwin) {
         return pwin->GetExtantDocument();
       }
@@ -1354,7 +1262,7 @@ nsContentUtils::IsCallerChrome()
 nsContentUtils::IsCallerChrome()
 {
   PRBool is_caller_chrome = PR_FALSE;
-  nsresult rv = sSecurityManager->SubjectPrincipalIsSystem(&is_caller_chrome);
+  nsresult rv = sLayoutRoots->sSecurityManager->SubjectPrincipalIsSystem(&is_caller_chrome);
   if (NS_FAILED(rv)) {
     return PR_FALSE;
   }
@@ -1399,13 +1307,13 @@ nsContentUtils::GetAncestors(nsIDOMNode*
 {
   NS_ENSURE_ARG_POINTER(aNode);
 
-  nsCOMPtr<nsIDOMNode> node(aNode);
-  nsCOMPtr<nsIDOMNode> ancestor;
-
-  do {
-    aArray->AppendElement(node.get());
-    node->GetParentNode(getter_AddRefs(ancestor));
-    node.swap(ancestor);
+  nsIDOMNode* node(aNode);
+  nsIDOMNode* ancestor = nsnull;
+
+  do {
+    aArray->AppendElement(node);
+    node->GetParentNode(&ancestor);
+    swap(node, ancestor);
   } while (node);
 
   return NS_OK;
@@ -1420,7 +1328,7 @@ nsContentUtils::GetAncestorsAndOffsets(n
 {
   NS_ENSURE_ARG_POINTER(aNode);
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
+  nsIContent* content(do_QueryInterface(aNode));
 
   if (!content) {
     return NS_ERROR_FAILURE;
@@ -1437,7 +1345,7 @@ nsContentUtils::GetAncestorsAndOffsets(n
   }
 
   // insert the node itself
-  aAncestorNodes->AppendElement(content.get());
+  aAncestorNodes->AppendElement(content);
   aAncestorOffsets->AppendElement(NS_INT32_TO_PTR(aOffset));
 
   // insert all the ancestors
@@ -1461,8 +1369,8 @@ nsContentUtils::GetCommonAncestor(nsIDOM
 {
   *aCommonAncestor = nsnull;
 
-  nsCOMPtr<nsINode> node1 = do_QueryInterface(aNode);
-  nsCOMPtr<nsINode> node2 = do_QueryInterface(aOther);
+  nsINode* node1 = do_QueryInterface(aNode);
+  nsINode* node2 = do_QueryInterface(aOther);
 
   NS_ENSURE_TRUE(node1 && node2, NS_ERROR_UNEXPECTED);
 
@@ -1709,8 +1617,8 @@ nsContentUtils::FindFirstChildWithResolv
   }
 
   // now look for children in XBL
-  nsCOMPtr<nsIDOMNodeList> children;
-  bindingManager->GetXBLChildNodesFor(aParent, getter_AddRefs(children));
+  nsIDOMNodeList* children = nsnull;
+  bindingManager->GetXBLChildNodesFor(aParent, &children);
   if (!children) {
     return nsnull;
   }
@@ -1718,9 +1626,9 @@ nsContentUtils::FindFirstChildWithResolv
   PRUint32 length;
   children->GetLength(&length);
   for (i = 0; i < length; i++) {
-    nsCOMPtr<nsIDOMNode> childNode;
-    children->Item(i, getter_AddRefs(childNode));
-    nsCOMPtr<nsIContent> childContent = do_QueryInterface(childNode);
+    nsIDOMNode* childNode = nsnull;
+    children->Item(i, &childNode);
+    nsIContent* childContent = do_QueryInterface(childNode);
     nsIAtom* tag = bindingManager->ResolveTag(childContent, &namespaceID);
     if (tag == aTag && namespaceID == aNamespace) {
       return childContent;
@@ -1895,12 +1803,12 @@ nsContentUtils::GenerateStateKey(nsICont
     return NS_OK;
   }
 
-  nsCOMPtr<nsIDOMElement> element(do_QueryInterface(aContent));
+  nsIDOMElement* element(do_QueryInterface(aContent));
   if (element && IsAutocompleteOff(element)) {
     return NS_OK;
   }
 
-  nsCOMPtr<nsIHTMLDocument> htmlDocument(do_QueryInterface(aContent->GetCurrentDoc()));
+  nsIHTMLDocument* htmlDocument(do_QueryInterface(aContent->GetCurrentDoc()));
 
   KeyAppendInt(partID, aKey);  // first append a partID
   // Make sure we can't possibly collide with an nsIStatefulFrame
@@ -1931,7 +1839,7 @@ nsContentUtils::GenerateStateKey(nsICont
     // XXX We don't need to use index if name is there
     // XXXbz We don't?  Why not?  I don't follow.
     //
-    nsCOMPtr<nsIFormControl> control(do_QueryInterface(aContent));
+    nsIFormControl* control(do_QueryInterface(aContent));
     if (control && htmlFormControls && htmlForms) {
 
       // Append the control type
@@ -1939,8 +1847,8 @@ nsContentUtils::GenerateStateKey(nsICont
 
       // If in a form, add form name / index of form / index in form
       PRInt32 index = -1;
-      nsCOMPtr<nsIDOMHTMLFormElement> formElement;
-      control->GetForm(getter_AddRefs(formElement));
+      nsIDOMHTMLFormElement* formElement = nsnull;
+      control->GetForm(&formElement);
       if (formElement) {
 
         if (IsAutocompleteOff(formElement)) {
@@ -1951,7 +1859,7 @@ nsContentUtils::GenerateStateKey(nsICont
         KeyAppendString(NS_LITERAL_CSTRING("f"), aKey);
 
         // Append the index of the form in the document
-        nsCOMPtr<nsIContent> formContent(do_QueryInterface(formElement));
+        nsIContent* formContent(do_QueryInterface(formElement));
         index = htmlForms->IndexOf(formContent, PR_FALSE);
         if (index <= -1) {
           //
@@ -1967,7 +1875,7 @@ nsContentUtils::GenerateStateKey(nsICont
           KeyAppendInt(index, aKey);
 
           // Append the index of the control in the form
-          nsCOMPtr<nsIForm> form(do_QueryInterface(formElement));
+          nsIForm* form(do_QueryInterface(formElement));
           form->IndexOfControl(control, &index);
 
           if (index > -1) {
@@ -2038,7 +1946,7 @@ nsContentUtils::NewURIWithDocumentCharse
 {
   return NS_NewURI(aResult, aSpec,
                    aDocument ? aDocument->GetDocumentCharacterSet().get() : nsnull,
-                   aBaseURI, sIOService);
+                   aBaseURI, sLayoutRoots->sIOService);
 }
 
 // static
@@ -2049,7 +1957,7 @@ nsContentUtils::BelongsInForm(nsIDOMHTML
   NS_PRECONDITION(aForm, "Must have a form");
   NS_PRECONDITION(aContent, "Must have a content node");
 
-  nsCOMPtr<nsIContent> form(do_QueryInterface(aForm));
+  nsIContent* form(do_QueryInterface(aForm));
 
   if (!form) {
     NS_ERROR("This should not happen, form is not an nsIContent!");
@@ -2171,7 +2079,7 @@ nsContentUtils::LookupNamespaceURI(nsICo
     return NS_OK;
   }
 
-  nsCOMPtr<nsIAtom> name;
+  nsIAtom* name = nsnull;
   if (!aNamespacePrefix.IsEmpty()) {
     name = do_GetAtom(aNamespacePrefix);
     NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
@@ -2205,12 +2113,12 @@ nsContentUtils::GetNodeInfoFromQName(con
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 nsID;
-  sNameSpaceManager->RegisterNameSpace(aNamespaceURI, nsID);
+  sLayoutRoots->sNameSpaceManager->RegisterNameSpace(aNamespaceURI, nsID);
   if (colon) {
     const PRUnichar* end;
     qName.EndReading(end);
 
-    nsCOMPtr<nsIAtom> prefix = do_GetAtom(Substring(qName.get(), colon));
+    nsIAtom* prefix = do_GetAtom(Substring(qName.get(), colon));
 
     rv = aNodeInfoManager->GetNodeInfo(Substring(colon + 1, end), prefix,
                                        nsID, aNodeInfo);
@@ -2258,8 +2166,8 @@ nsContentUtils::SplitExpatName(const PRU
 
   const PRUnichar *nameStart;
   if (uriEnd) {
-    if (sNameSpaceManager) {
-      sNameSpaceManager->RegisterNameSpace(nsDependentSubstring(aExpatName,
+    if (sLayoutRoots->sNameSpaceManager) {
+      sLayoutRoots->sNameSpaceManager->RegisterNameSpace(nsDependentSubstring(aExpatName,
                                                                 uriEnd),
                                            *aNameSpaceID);
     }
@@ -2318,15 +2226,15 @@ nsContentUtils::CanLoadImage(nsIURI* aUR
   PRUint32 appType = nsIDocShell::APP_TYPE_UNKNOWN;
 
   {
-    nsCOMPtr<nsISupports> container = aLoadingDocument->GetContainer();
-    nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
+    nsISupports* container = aLoadingDocument->GetContainer();
+    nsIDocShellTreeItem* docShellTreeItem =
       do_QueryInterface(container);
 
     if (docShellTreeItem) {
-      nsCOMPtr<nsIDocShellTreeItem> root;
-      docShellTreeItem->GetRootTreeItem(getter_AddRefs(root));
-
-      nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(root));
+      nsIDocShellTreeItem* root = nsnull;
+      docShellTreeItem->GetRootTreeItem(&root);
+
+      nsIDocShell* docShell(do_QueryInterface(root));
 
       if (!docShell || NS_FAILED(docShell->GetAppType(&appType))) {
         appType = nsIDocShell::APP_TYPE_UNKNOWN;
@@ -2338,7 +2246,7 @@ nsContentUtils::CanLoadImage(nsIURI* aUR
     // Editor apps get special treatment here, editors can load images
     // from anywhere.  This allows editor to insert images from file://
     // into documents that are being edited.
-    rv = sSecurityManager->
+    rv = sLayoutRoots->sSecurityManager->
       CheckLoadURIWithPrincipal(aLoadingPrincipal, aURI,
                                 nsIScriptSecurityManager::ALLOW_CHROME);
     if (NS_FAILED(rv)) {
@@ -2361,7 +2269,7 @@ nsContentUtils::CanLoadImage(nsIURI* aUR
                                  nsnull,         //extra
                                  &decision,
                                  GetContentPolicy(),
-                                 sSecurityManager);
+                                 sLayoutRoots->sSecurityManager);
 
   if (aImageBlockingStatus) {
     *aImageBlockingStatus =
@@ -2382,12 +2290,12 @@ nsContentUtils::LoadImage(nsIURI* aURI, 
   NS_PRECONDITION(aLoadingPrincipal, "Must have a principal");
   NS_PRECONDITION(aRequest, "Null out param");
 
-  if (!sImgLoader) {
+  if (!sLayoutRoots->sImgLoader) {
     // nothing we can do here
     return NS_OK;
   }
 
-  nsCOMPtr<nsILoadGroup> loadGroup = aLoadingDocument->GetDocumentLoadGroup();
+  nsILoadGroup* loadGroup = aLoadingDocument->GetDocumentLoadGroup();
   NS_ASSERTION(loadGroup, "Could not get loadgroup; onload may fire too early");
 
   nsIURI *documentURI = aLoadingDocument->GetDocumentURI();
@@ -2400,7 +2308,7 @@ nsContentUtils::LoadImage(nsIURI* aURI, 
 
   // XXXbz using "documentURI" for the initialDocumentURI is not quite
   // right, but the best we can do here...
-  return sImgLoader->LoadImage(aURI,                 /* uri to load */
+  return sLayoutRoots->sImgLoader->LoadImage(aURI,                 /* uri to load */
                                documentURI,          /* initialDocumentURI */
                                aReferrer,            /* referrer */
                                loadGroup,            /* loadgroup */
@@ -2413,7 +2321,7 @@ nsContentUtils::LoadImage(nsIURI* aURI, 
 }
 
 // static
-already_AddRefed<nsIImage>
+nsIImage*
 nsContentUtils::GetImageFromContent(nsIImageLoadingContent* aContent,
                                     imgIRequest **aRequest)
 {
@@ -2423,39 +2331,39 @@ nsContentUtils::GetImageFromContent(nsII
 
   NS_ENSURE_TRUE(aContent, nsnull);
 
-  nsCOMPtr<imgIRequest> imgRequest;
+  imgIRequest* imgRequest = nsnull;
   aContent->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
-                      getter_AddRefs(imgRequest));
+                      &imgRequest);
   if (!imgRequest) {
     return nsnull;
   }
 
-  nsCOMPtr<imgIContainer> imgContainer;
-  imgRequest->GetImage(getter_AddRefs(imgContainer));
+  imgIContainer* imgContainer = nsnull;
+  imgRequest->GetImage(&imgContainer);
 
   if (!imgContainer) {
     return nsnull;
   }
 
-  nsCOMPtr<gfxIImageFrame> imgFrame;
-  imgContainer->GetFrameAt(0, getter_AddRefs(imgFrame));
+  gfxIImageFrame* imgFrame = nsnull;
+  imgContainer->GetFrameAt(0, &imgFrame);
 
   if (!imgFrame) {
     return nsnull;
   }
 
-  nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(imgFrame);
+  nsIInterfaceRequestor* ir = do_QueryInterface(imgFrame);
 
   if (!ir) {
     return nsnull;
   }
 
   if (aRequest) {
-    imgRequest.swap(*aRequest);
+    swap(imgRequest, *aRequest);
   }
 
   nsIImage* image = nsnull;
-  CallGetInterface(ir.get(), &image);
+  CallGetInterface(ir, &image);
   return image;
 }
 
@@ -2465,14 +2373,14 @@ nsContentUtils::IsDraggableImage(nsICont
 {
   NS_PRECONDITION(aContent, "Must have content node to test");
 
-  nsCOMPtr<nsIImageLoadingContent> imageContent(do_QueryInterface(aContent));
+  nsIImageLoadingContent* imageContent(do_QueryInterface(aContent));
   if (!imageContent) {
     return PR_FALSE;
   }
 
-  nsCOMPtr<imgIRequest> imgRequest;
+  imgIRequest* imgRequest = nsnull;
   imageContent->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
-                           getter_AddRefs(imgRequest));
+                           &imgRequest);
 
   // XXXbz It may be draggable even if the request resulted in an error.  Why?
   // Not sure; that's what the old nsContentAreaDragDrop/nsFrame code did.
@@ -2482,8 +2390,8 @@ nsContentUtils::IsDraggableImage(nsICont
 // static
 PRBool
 nsContentUtils::IsDraggableLink(nsIContent* aContent) {
-  nsCOMPtr<nsIURI> absURI;
-  return aContent->IsLink(getter_AddRefs(absURI));
+  nsIURI* absURI = nsnull;
+  return aContent->IsLink(&absURI);
 }
 
 // static
@@ -2492,8 +2400,8 @@ nsContentUtils::GetCharPref(const char *
 {
   nsAdoptingCString result;
 
-  if (sPrefBranch) {
-    sPrefBranch->GetCharPref(aPref, getter_Copies(result));
+  if (sLayoutRoots->sPrefBranch) {
+    sLayoutRoots->sPrefBranch->GetCharPref(aPref, getter_Copies(result));
   }
 
   return result;
@@ -2505,8 +2413,8 @@ nsContentUtils::GetBoolPref(const char *
 {
   PRBool result;
 
-  if (!sPrefBranch ||
-      NS_FAILED(sPrefBranch->GetBoolPref(aPref, &result))) {
+  if (!sLayoutRoots->sPrefBranch ||
+      NS_FAILED(sLayoutRoots->sPrefBranch->GetBoolPref(aPref, &result))) {
     result = aDefault;
   }
 
@@ -2519,8 +2427,8 @@ nsContentUtils::GetIntPref(const char *a
 {
   PRInt32 result;
 
-  if (!sPrefBranch ||
-      NS_FAILED(sPrefBranch->GetIntPref(aPref, &result))) {
+  if (!sLayoutRoots->sPrefBranch ||
+      NS_FAILED(sLayoutRoots->sPrefBranch->GetIntPref(aPref, &result))) {
     result = aDefault;
   }
 
@@ -2533,10 +2441,10 @@ nsContentUtils::GetLocalizedStringPref(c
 {
   nsAdoptingString result;
 
-  if (sPrefBranch) {
-    nsCOMPtr<nsIPrefLocalizedString> prefLocalString;
-    sPrefBranch->GetComplexValue(aPref, NS_GET_IID(nsIPrefLocalizedString),
-                                 getter_AddRefs(prefLocalString));
+  if (sLayoutRoots->sPrefBranch) {
+    nsIPrefLocalizedString* prefLocalString = nsnull;
+    sLayoutRoots->sPrefBranch->GetComplexValue(aPref, NS_GET_IID(nsIPrefLocalizedString),
+                                 (void**)&prefLocalString);
     if (prefLocalString) {
       prefLocalString->GetData(getter_Copies(result));
     }
@@ -2551,10 +2459,10 @@ nsContentUtils::GetStringPref(const char
 {
   nsAdoptingString result;
 
-  if (sPrefBranch) {
-    nsCOMPtr<nsISupportsString> theString;
-    sPrefBranch->GetComplexValue(aPref, NS_GET_IID(nsISupportsString),
-                                 getter_AddRefs(theString));
+  if (sLayoutRoots->sPrefBranch) {
+    nsISupportsString* theString = nsnull;
+    sLayoutRoots->sPrefBranch->GetComplexValue(aPref, NS_GET_IID(nsISupportsString),
+                                 (void**)&theString);
     if (theString) {
       theString->ToString(getter_Copies(result));
     }
@@ -2569,8 +2477,8 @@ nsContentUtils::RegisterPrefCallback(con
                                      PrefChangedFunc aCallback,
                                      void * aClosure)
 {
-  if (sPref)
-    sPref->RegisterCallback(aPref, aCallback, aClosure);
+  if (sLayoutRoots->sPref)
+    sLayoutRoots->sPref->RegisterCallback(aPref, aCallback, aClosure);
 }
 
 // static
@@ -2579,8 +2487,8 @@ nsContentUtils::UnregisterPrefCallback(c
                                        PrefChangedFunc aCallback,
                                        void * aClosure)
 {
-  if (sPref)
-    sPref->UnregisterCallback(aPref, aCallback, aClosure);
+  if (sLayoutRoots->sPref)
+    sLayoutRoots->sPref->UnregisterCallback(aPref, aCallback, aClosure);
 }
 
 static int PR_CALLBACK
@@ -2650,7 +2558,7 @@ IsContextOnStack(nsIJSContextStack *aSta
   if (ctx == aContext)
     return PR_TRUE;
 
-  nsCOMPtr<nsIJSContextStackIterator>
+  nsIJSContextStackIterator*
     iterator(do_CreateInstance("@mozilla.org/js/xpc/ContextStackIterator;1"));
   NS_ENSURE_TRUE(iterator, PR_FALSE);
 
@@ -2682,9 +2590,9 @@ nsCxPusher::Push(nsISupports *aCurrentTa
     return PR_FALSE;
   }
 
-  nsCOMPtr<nsIScriptGlobalObject> sgo;
-  nsCOMPtr<nsINode> node(do_QueryInterface(aCurrentTarget));
-  nsCOMPtr<nsIDocument> document;
+  nsIScriptGlobalObject* sgo = nsnull;
+  nsINode* node(do_QueryInterface(aCurrentTarget));
+  nsIDocument* document = nsnull;
 
   if (node) {
     document = node->GetOwnerDoc();
@@ -2798,17 +2706,17 @@ static const char gPropertiesFiles[nsCon
 /* static */ nsresult
 nsContentUtils::EnsureStringBundle(PropertiesFile aFile)
 {
-  if (!sStringBundles[aFile]) {
-    if (!sStringBundleService) {
+  if (!sLayoutRoots->sStringBundles[aFile]) {
+    if (!sLayoutRoots->sStringBundleService) {
       nsresult rv =
-        CallGetService(NS_STRINGBUNDLE_CONTRACTID, &sStringBundleService);
+        CallGetService(NS_STRINGBUNDLE_CONTRACTID, &sLayoutRoots->sStringBundleService);
       NS_ENSURE_SUCCESS(rv, rv);
     }
     nsIStringBundle *bundle;
     nsresult rv =
-      sStringBundleService->CreateBundle(gPropertiesFiles[aFile], &bundle);
-    NS_ENSURE_SUCCESS(rv, rv);
-    sStringBundles[aFile] = bundle; // transfer ownership
+      sLayoutRoots->sStringBundleService->CreateBundle(gPropertiesFiles[aFile], &bundle);
+    NS_ENSURE_SUCCESS(rv, rv);
+    sLayoutRoots->sStringBundles[aFile] = bundle; // transfer ownership
   }
   return NS_OK;
 }
@@ -2820,7 +2728,7 @@ nsresult nsContentUtils::GetLocalizedStr
 {
   nsresult rv = EnsureStringBundle(aFile);
   NS_ENSURE_SUCCESS(rv, rv);
-  nsIStringBundle *bundle = sStringBundles[aFile];
+  nsIStringBundle *bundle = sLayoutRoots->sStringBundles[aFile];
 
   return bundle->GetStringFromName(NS_ConvertASCIItoUTF16(aKey).get(),
                                    getter_Copies(aResult));
@@ -2835,7 +2743,7 @@ nsresult nsContentUtils::FormatLocalized
 {
   nsresult rv = EnsureStringBundle(aFile);
   NS_ENSURE_SUCCESS(rv, rv);
-  nsIStringBundle *bundle = sStringBundles[aFile];
+  nsIStringBundle *bundle = sLayoutRoots->sStringBundles[aFile];
 
   return bundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aKey).get(),
                                       aParams, aParamsLength,
@@ -2859,8 +2767,8 @@ nsContentUtils::ReportToConsole(Properti
                "parameters and 0.");
 
   nsresult rv;
-  if (!sConsoleService) { // only need to bother null-checking here
-    rv = CallGetService(NS_CONSOLESERVICE_CONTRACTID, &sConsoleService);
+  if (!sLayoutRoots->sConsoleService) { // only need to bother null-checking here
+    rv = CallGetService(NS_CONSOLESERVICE_CONTRACTID, &sLayoutRoots->sConsoleService);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
@@ -2878,7 +2786,7 @@ nsContentUtils::ReportToConsole(Properti
   if (aURI)
     aURI->GetSpec(spec);
 
-  nsCOMPtr<nsIScriptError> errorObject =
+  nsIScriptError* errorObject =
       do_CreateInstance(NS_SCRIPTERROR_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = errorObject->Init(errorText.get(),
@@ -2888,7 +2796,7 @@ nsContentUtils::ReportToConsole(Properti
                          aErrorFlags, aCategory);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return sConsoleService->LogMessage(errorObject);
+  return sLayoutRoots->sConsoleService->LogMessage(errorObject);
 }
 
 PRBool
@@ -2898,8 +2806,8 @@ nsContentUtils::IsChromeDoc(nsIDocument 
     return PR_FALSE;
   }
   
-  nsCOMPtr<nsIPrincipal> systemPrincipal;
-  sSecurityManager->GetSystemPrincipal(getter_AddRefs(systemPrincipal));
+  nsIPrincipal* systemPrincipal = nsnull;
+  sLayoutRoots->sSecurityManager->GetSystemPrincipal(&systemPrincipal);
 
   return aDocument->NodePrincipal() == systemPrincipal;
 }
@@ -2930,33 +2838,44 @@ nsContentUtils::GetContentPolicy()
 nsContentUtils::GetContentPolicy()
 {
   if (!sTriedToGetContentPolicy) {
-    CallGetService(NS_CONTENTPOLICY_CONTRACTID, &sContentPolicyService);
+    CallGetService(NS_CONTENTPOLICY_CONTRACTID, &sLayoutRoots->sContentPolicyService);
     // It's OK to not have a content policy service
     sTriedToGetContentPolicy = PR_TRUE;
   }
 
-  return sContentPolicyService;
-}
-
-// static
-nsresult
-nsAutoGCRoot::AddJSGCRoot(void* aPtr, const char* aName)
-{
-  if (!sJSScriptRuntime) {
-    nsresult rv = CallGetService("@mozilla.org/js/xpc/RuntimeService;1",
-                                 &sJSRuntimeService);
-    NS_ENSURE_TRUE(sJSRuntimeService, rv);
-
-    sJSRuntimeService->GetRuntime(&sJSScriptRuntime);
-    if (!sJSScriptRuntime) {
-      NS_RELEASE(sJSRuntimeService);
+  return sLayoutRoots->sContentPolicyService;
+}
+
+// static
+JSRuntime*
+nsContentUtils::GetJSScriptRuntime()
+{
+  if (!sLayoutRoots->sJSScriptRuntime) {
+    CallGetService("@mozilla.org/js/xpc/RuntimeService;1",
+                   &sLayoutRoots->sJSRuntimeService);
+    NS_ENSURE_TRUE(sLayoutRoots->sJSRuntimeService, nsnull);
+
+    sLayoutRoots->sJSRuntimeService->
+      GetRuntime(&sLayoutRoots->sJSScriptRuntime);
+    if (!sLayoutRoots->sJSScriptRuntime) {
       NS_WARNING("Unable to get JS runtime from JS runtime service");
-      return NS_ERROR_FAILURE;
-    }
-  }
+      sLayoutRoots->sJSRuntimeService = nsnull;
+      return nsnull;
+    }
+  }  
+  return sLayoutRoots->sJSScriptRuntime;
+}
+
+// static
+nsresult
+nsContentUtils::AddJSGCRoot(void* aPtr, const char* aName)
+{
+  JSRuntime *rt = GetJSScriptRuntime();
+  if (!rt)
+    return NS_ERROR_FAILURE;
 
   PRBool ok;
-  ok = ::JS_AddNamedRootRT(sJSScriptRuntime, aPtr, aName);
+  ok = ::JS_AddNamedRootRT(rt, aPtr, aName);
   if (!ok) {
     NS_WARNING("JS_AddNamedRootRT failed");
     return NS_ERROR_OUT_OF_MEMORY;
@@ -2967,14 +2886,12 @@ nsAutoGCRoot::AddJSGCRoot(void* aPtr, co
 
 /* static */
 nsresult
-nsAutoGCRoot::RemoveJSGCRoot(void* aPtr)
-{
-  if (!sJSScriptRuntime) {
-    NS_NOTREACHED("Trying to remove a JS GC root when none were added");
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  ::JS_RemoveRootRT(sJSScriptRuntime, aPtr);
+nsContentUtils::RemoveJSGCRoot(void* aPtr)
+{
+  JSRuntime *rt = GetJSScriptRuntime();
+  NS_ASSERTION(rt, "Removing a JSGC root when none were added?");
+
+  ::JS_RemoveRootRT(rt, aPtr);
 
   return NS_OK;
 }
@@ -2989,7 +2906,7 @@ nsContentUtils::IsEventAttributeName(nsI
     return PR_FALSE;
 
   EventNameMapping mapping;
-  return (sEventTable->Get(aName, &mapping) && mapping.mType & aType);
+  return (sLayoutRoots->sEventTable.Get(aName, &mapping) && mapping.mType & aType);
 }
 
 // static
@@ -2997,7 +2914,7 @@ nsContentUtils::GetEventId(nsIAtom* aNam
 nsContentUtils::GetEventId(nsIAtom* aName)
 {
   EventNameMapping mapping;
-  if (sEventTable->Get(aName, &mapping))
+  if (sLayoutRoots->sEventTable.Get(aName, &mapping))
     return mapping.mId;
 
   return NS_USER_DEFINED_EVENT;
@@ -3010,16 +2927,16 @@ nsContentUtils::DispatchTrustedEvent(nsI
                                      PRBool aCanBubble, PRBool aCancelable,
                                      PRBool *aDefaultAction)
 {
-  nsCOMPtr<nsIDOMDocumentEvent> docEvent(do_QueryInterface(aDoc));
-  nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(aTarget));
+  nsIDOMDocumentEvent* docEvent(do_QueryInterface(aDoc));
+  nsIDOMEventTarget* target(do_QueryInterface(aTarget));
   NS_ENSURE_TRUE(docEvent && target, NS_ERROR_INVALID_ARG);
 
-  nsCOMPtr<nsIDOMEvent> event;
+  nsIDOMEvent* event = nsnull;
   nsresult rv =
-    docEvent->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
+    docEvent->CreateEvent(NS_LITERAL_STRING("Events"), &event);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsIPrivateDOMEvent* privateEvent(do_QueryInterface(event));
   NS_ENSURE_TRUE(privateEvent, NS_ERROR_FAILURE);
 
   rv = event->InitEvent(aEventName, aCanBubble, aCancelable);
@@ -3059,7 +2976,7 @@ nsContentUtils::MatchElementId(nsIConten
   NS_PRECONDITION(!aId.IsEmpty(), "Will match random elements");
   
   // ID attrs are generally stored as atoms, so just atomize this up front
-  nsCOMPtr<nsIAtom> id(do_GetAtom(aId));
+  nsIAtom* id(do_GetAtom(aId));
   if (!id) {
     // OOM, so just bail
     return nsnull;
@@ -3082,14 +2999,14 @@ nsContentUtils::ConvertStringFromCharset
   }
 
   nsresult rv;
-  nsCOMPtr<nsICharsetConverterManager> ccm =
+  nsICharsetConverterManager* ccm =
     do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
   if (NS_FAILED(rv))
     return rv;
 
-  nsCOMPtr<nsIUnicodeDecoder> decoder;
+  nsIUnicodeDecoder* decoder = nsnull;
   rv = ccm->GetUnicodeDecoder(PromiseFlatCString(aCharset).get(),
-                              getter_AddRefs(decoder));
+                              &decoder);
   if (NS_FAILED(rv))
     return rv;
 
@@ -3156,13 +3073,120 @@ nsContentUtils::CheckForBOM(const unsign
   return found;
 }
 
+static PRBool EqualExceptRef(nsIURL* aURL1, nsIURL* aURL2)
+{
+  nsIURI* u1 = nsnull;
+  nsIURI* u2 = nsnull;
+
+  nsresult rv = aURL1->Clone(&u1);
+  if (NS_SUCCEEDED(rv)) {
+    rv = aURL2->Clone(&u2);
+  }
+  if (NS_FAILED(rv))
+    return PR_FALSE;
+
+  nsIURL* url1 = do_QueryInterface(u1);
+  nsIURL* url2 = do_QueryInterface(u2);
+  if (!url1 || !url2) {
+    NS_WARNING("Cloning a URL produced a non-URL");
+    return PR_FALSE;
+  }
+  url1->SetRef(EmptyCString());
+  url2->SetRef(EmptyCString());
+
+  PRBool equal;
+  rv = url1->Equals(url2, &equal);
+  return NS_SUCCEEDED(rv) && equal;
+}
+
 /* static */
 nsIContent*
 nsContentUtils::GetReferencedElement(nsIURI* aURI, nsIContent *aFromContent)
 {
-  nsReferencedElement ref;
-  ref.Reset(aFromContent, aURI);
-  return ref.get();
+  nsIURL* url = do_QueryInterface(aURI);
+  if (!url)
+    return nsnull;
+
+  nsCAutoString refPart;
+  url->GetRef(refPart);
+  // Unescape %-escapes in the reference. The result will be in the
+  // origin charset of the URL, hopefully...
+  NS_UnescapeURL(refPart);
+
+  nsCAutoString charset;
+  url->GetOriginCharset(charset);
+  nsAutoString ref;
+  nsresult rv = ConvertStringFromCharset(charset, refPart, ref);
+  if (NS_FAILED(rv)) {
+    CopyUTF8toUTF16(refPart, ref);
+  }
+  if (ref.IsEmpty())
+    return nsnull;
+
+  // Get the current document
+  nsIDocument *doc = aFromContent->GetCurrentDoc();
+  if (!doc)
+    return nsnull;
+
+  // This will be the URI of the document the content belongs to
+  // (the URI of the XBL document if the content is anonymous
+  // XBL content)
+  nsIURL* documentURL = do_QueryInterface(doc->GetDocumentURI());
+  nsIContent* bindingParent = aFromContent->GetBindingParent();
+  PRBool isXBL = PR_FALSE;
+  if (bindingParent) {
+    nsXBLBinding* binding = doc->BindingManager()->GetBinding(bindingParent);
+    if (binding) {
+      // XXX sXBL/XBL2 issue
+      // If this is an anonymous XBL element then the URI is
+      // relative to the binding document. A full fix requires a
+      // proper XBL2 implementation but for now URIs that are
+      // relative to the binding document should be resolve to the
+      // copy of the target element that has been inserted into the
+      // bound document.
+      documentURL = do_QueryInterface(binding->PrototypeBinding()->DocURI());
+      isXBL = PR_TRUE;
+    }
+  }
+  if (!documentURL)
+    return nsnull;
+
+  if (!EqualExceptRef(url, documentURL)) {
+    // Oops -- we don't support off-document references
+    return nsnull;
+  }
+
+  // Get the element
+  nsIContent* content = nsnull;
+  if (isXBL) {
+    nsIDOMNodeList* anonymousChildren = nsnull;
+    doc->BindingManager()->
+      GetAnonymousNodesFor(bindingParent, &anonymousChildren);
+
+    if (anonymousChildren) {
+      PRUint32 length;
+      anonymousChildren->GetLength(&length);
+      for (PRUint32 i = 0; i < length && !content; ++i) {
+        nsIDOMNode* node = nsnull;
+        anonymousChildren->Item(i, &node);
+        nsIContent* c = do_QueryInterface(node);
+        if (c) {
+          content = MatchElementId(c, ref);
+        }
+      }
+    }
+  } else {
+    nsIDOMDocument* domDoc = do_QueryInterface(doc);
+    NS_ASSERTION(domDoc, "Content doesn't reference a dom Document");
+
+    nsIDOMElement* element = nsnull;
+    rv = domDoc->GetElementById(ref, &element);
+    if (element) {
+      content = do_QueryInterface(element);
+    }
+  }
+
+  return content;
 }
 
 /* static */
@@ -3187,7 +3211,7 @@ nsContentUtils::HasMutationListeners(nsI
   }
 
   // global object will be null for documents that don't have windows.
-  nsCOMPtr<nsPIDOMWindow> window;
+  nsPIDOMWindow* window = nsnull;
   window = do_QueryInterface(doc->GetScriptGlobalObject());
   // This relies on nsEventListenerManager::AddEventListener, which sets
   // all mutation bits when there is a listener for DOMSubtreeModified event.
@@ -3203,10 +3227,10 @@ nsContentUtils::HasMutationListeners(nsI
   doc->MayDispatchMutationEvent(aTargetForSubtreeModified);
 
   // If we have a window, we can check it for mutation listeners now.
-  nsCOMPtr<nsPIDOMEventTarget> piTarget(do_QueryInterface(window));
+  nsPIDOMEventTarget* piTarget(do_QueryInterface(window));
   if (piTarget) {
-    nsCOMPtr<nsIEventListenerManager> manager;
-    piTarget->GetListenerManager(PR_FALSE, getter_AddRefs(manager));
+    nsIEventListenerManager* manager = nsnull;
+    piTarget->GetListenerManager(PR_FALSE, &manager);
     if (manager) {
       PRBool hasListeners = PR_FALSE;
       manager->HasMutationListeners(&hasListeners);
@@ -3220,8 +3244,8 @@ nsContentUtils::HasMutationListeners(nsI
   // might not be in our chain.  If we don't have a window, we might have a
   // mutation listener.  Check quickly to see.
   while (aNode) {
-    nsCOMPtr<nsIEventListenerManager> manager;
-    aNode->GetListenerManager(PR_FALSE, getter_AddRefs(manager));
+    nsIEventListenerManager* manager = nsnull;
+    aNode->GetListenerManager(PR_FALSE, &manager);
     if (manager) {
       PRBool hasListeners = PR_FALSE;
       manager->HasMutationListeners(&hasListeners);
@@ -3270,7 +3294,6 @@ nsContentUtils::GetListenerManager(nsINo
                                           PL_DHASH_LOOKUP));
     if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
       *aResult = entry->mListenerManager;
-      NS_ADDREF(*aResult);
     }
     return NS_OK;
   }
@@ -3299,7 +3322,7 @@ nsContentUtils::GetListenerManager(nsINo
     aNode->SetFlags(NODE_HAS_LISTENERMANAGER);
   }
 
-  NS_ADDREF(*aResult = entry->mListenerManager);
+  *aResult = entry->mListenerManager;
 
   return NS_OK;
 }
@@ -3314,8 +3337,8 @@ nsContentUtils::RemoveListenerManager(ns
                  (PL_DHashTableOperate(&sEventListenerManagersHash, aNode,
                                           PL_DHASH_LOOKUP));
     if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
-      nsCOMPtr<nsIEventListenerManager> listenerManager;
-      listenerManager.swap(entry->mListenerManager);
+      nsIEventListenerManager* listenerManager = nsnull;
+      swap(listenerManager, entry->mListenerManager);
       // Remove the entry and *then* do operations that could cause further
       // modification of sEventListenerManagersHash.  See bug 334177.
       PL_DHashTableRawRemove(&sEventListenerManagersHash, entry);
@@ -3442,7 +3465,7 @@ nsContentUtils::CreateContextualFragment
   LossyCopyUTF16toASCII(buf, contentType);
   bCaseSensitive = document->IsCaseSensitive();
 
-  nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(document));
+  nsIHTMLDocument* htmlDoc(do_QueryInterface(document));
   PRBool bHTML = htmlDoc && !bCaseSensitive;
 
   // See if the document has a cached fragment parser. nsHTMLDocument is the
@@ -3534,7 +3557,7 @@ nsContentUtils::CreateDocument(const nsA
                                   PR_TRUE);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIDocument> document = do_QueryInterface(*aResult);
+  nsIDocument* document = do_QueryInterface(*aResult);
   document->SetScriptHandlingObject(aEventObject);
   return NS_OK;
 }
@@ -3584,8 +3607,8 @@ nsContentUtils::SetNodeTextContent(nsICo
     return NS_OK;
   }
 
-  nsCOMPtr<nsIContent> textContent;
-  nsresult rv = NS_NewTextNode(getter_AddRefs(textContent),
+  nsIContent* textContent = nsnull;
+  nsresult rv = NS_NewTextNode(&textContent,
                                aContent->NodeInfo()->NodeInfoManager());
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -3685,14 +3708,14 @@ nsIDOMScriptObjectFactory*
 nsIDOMScriptObjectFactory*
 nsContentUtils::GetDOMScriptObjectFactory()
 {
-  if (!sDOMScriptObjectFactory) {
+  if (!sLayoutRoots->sDOMScriptObjectFactory) {
     static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
                          NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
 
-    CallGetService(kDOMScriptObjectFactoryCID, &sDOMScriptObjectFactory);
-  }
-
-  return sDOMScriptObjectFactory;
+    CallGetService(kDOMScriptObjectFactoryCID, &sLayoutRoots->sDOMScriptObjectFactory);
+  }
+
+  return sLayoutRoots->sDOMScriptObjectFactory;
 }
 
 /* static */
@@ -3705,7 +3728,7 @@ nsContentUtils::HoldScriptObject(PRUint3
   nsresult rv;
 
   PRUint32 langIndex = NS_STID_INDEX(aLangID);
-  nsIScriptRuntime *runtime = sScriptRuntimes[langIndex];
+  nsIScriptRuntime *runtime = sLayoutRoots->sScriptRuntimes[langIndex];
   if (!runtime) {
     nsIDOMScriptObjectFactory *factory = GetDOMScriptObjectFactory();
     NS_ENSURE_TRUE(factory, NS_ERROR_FAILURE);
@@ -3713,15 +3736,15 @@ nsContentUtils::HoldScriptObject(PRUint3
     rv = factory->GetScriptRuntimeByID(aLangID, &runtime);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    // This makes sScriptRuntimes hold a strong ref.
-    sScriptRuntimes[langIndex] = runtime;
+    // This makes sLayoutRoots->sScriptRuntimes hold a strong ref.
+    sLayoutRoots->sScriptRuntimes[langIndex] = runtime;
   }
 
   rv = runtime->HoldScriptObject(aObject);
   NS_ENSURE_SUCCESS(rv, rv);
 
   ++sScriptRootCount[langIndex];
-  NS_LOG_ADDREF(sScriptRuntimes[langIndex], sScriptRootCount[langIndex],
+  NS_LOG_ADDREF(sLayoutRoots->sScriptRuntimes[langIndex], sScriptRootCount[langIndex],
                 "HoldScriptObject", sizeof(void*));
 
   return NS_OK;
@@ -3736,11 +3759,11 @@ nsContentUtils::DropScriptObject(PRUint3
   NS_ASSERTION(aLangID != nsIProgrammingLanguage::JAVASCRIPT,
                "Should use DropJSObjects.");
   PRUint32 langIndex = NS_STID_INDEX(aLangID);
-  NS_LOG_RELEASE(sScriptRuntimes[langIndex], sScriptRootCount[langIndex] - 1,
+  NS_LOG_RELEASE(sLayoutRoots->sScriptRuntimes[langIndex], sScriptRootCount[langIndex] - 1,
                  "HoldScriptObject");
-  sScriptRuntimes[langIndex]->DropScriptObject(aObject);
+  sLayoutRoots->sScriptRuntimes[langIndex]->DropScriptObject(aObject);
   if (--sScriptRootCount[langIndex] == 0) {
-    NS_RELEASE(sScriptRuntimes[langIndex]);
+    NS_RELEASE(sLayoutRoots->sScriptRuntimes[langIndex]);
   }
 }
 
@@ -3770,7 +3793,7 @@ nsContentUtils::NotifyInstalledMenuKeybo
 
 static PRBool SchemeIs(nsIURI* aURI, const char* aScheme)
 {
-  nsCOMPtr<nsIURI> baseURI = NS_GetInnermostURI(aURI);
+  nsIURI* baseURI = NS_GetInnermostURI(aURI);
   NS_ENSURE_TRUE(baseURI, PR_FALSE);
 
   PRBool isScheme = PR_FALSE;
@@ -3791,15 +3814,15 @@ nsContentUtils::CheckSecurityBeforeLoad(
   NS_PRECONDITION(aLoadingPrincipal, "Must have a loading principal here");
 
   PRBool isSystemPrin = PR_FALSE;
-  if (NS_SUCCEEDED(sSecurityManager->IsSystemPrincipal(aLoadingPrincipal,
-                                                       &isSystemPrin)) &&
+  if (NS_SUCCEEDED(sLayoutRoots->sSecurityManager->
+                   IsSystemPrincipal(aLoadingPrincipal, &isSystemPrin)) &&
       isSystemPrin) {
     return NS_OK;
   }
   
   // XXXbz do we want to fast-path skin stylesheets loading XBL here somehow?
   // CheckLoadURIWithPrincipal
-  nsresult rv = sSecurityManager->
+  nsresult rv = sLayoutRoots->sSecurityManager->
     CheckLoadURIWithPrincipal(aLoadingPrincipal, aURIToLoad, aCheckLoadFlags);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -3813,7 +3836,7 @@ nsContentUtils::CheckSecurityBeforeLoad(
                                  aExtra,
                                  &shouldLoad,
                                  GetContentPolicy(),
-                                 sSecurityManager);
+                                 sLayoutRoots->sSecurityManager);
   NS_ENSURE_SUCCESS(rv, rv);
   if (NS_CP_REJECTED(shouldLoad)) {
     return NS_ERROR_CONTENT_BLOCKED;
@@ -3856,13 +3879,13 @@ nsContentUtils::TriggerLink(nsIContent *
   // Check that this page is allowed to load this URI.
   nsresult proceed = NS_OK;
 
-  if (sSecurityManager) {
+  if (sLayoutRoots->sSecurityManager) {
     PRUint32 flag =
       aIsUserTriggered ?
       (PRUint32)nsIScriptSecurityManager::STANDARD :
       (PRUint32)nsIScriptSecurityManager::LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT;
     proceed =
-      sSecurityManager->CheckLoadURIWithPrincipal(aContent->NodePrincipal(),
+      sLayoutRoots->sSecurityManager->CheckLoadURIWithPrincipal(aContent->NodePrincipal(),
                                                   aLinkURI, flag);
   }
 
@@ -4121,7 +4144,7 @@ nsContentUtils::AddScriptBlocker()
   if (!sScriptBlockerCount) {
     NS_ASSERTION(sRunnersCountAtFirstBlocker == 0,
                  "Should not already have a count");
-    sRunnersCountAtFirstBlocker = sBlockedScriptRunners->Count();
+    sRunnersCountAtFirstBlocker = sLayoutRoots->sBlockedScriptRunners.Count();
   }
   ++sScriptBlockerCount;
 }
@@ -4137,18 +4160,19 @@ nsContentUtils::RemoveScriptBlocker()
   }
 
   PRUint32 firstBlocker = sRunnersCountAtFirstBlocker;
-  PRUint32 lastBlocker = sBlockedScriptRunners->Count();
+  PRUint32 lastBlocker = sLayoutRoots->sBlockedScriptRunners.Count();
   sRunnersCountAtFirstBlocker = 0;
   NS_ASSERTION(firstBlocker <= lastBlocker,
                "bad sRunnersCountAtFirstBlocker");
 
   while (firstBlocker < lastBlocker) {
-    nsCOMPtr<nsIRunnable> runnable = (*sBlockedScriptRunners)[firstBlocker];
-    sBlockedScriptRunners->RemoveObjectAt(firstBlocker);
+    nsCOMPtr<nsIRunnable> runnable =
+      (sLayoutRoots->sBlockedScriptRunners)[firstBlocker];
+    sLayoutRoots->sBlockedScriptRunners.RemoveObjectAt(firstBlocker);
     --lastBlocker;
 
     runnable->Run();
-    NS_ASSERTION(lastBlocker == sBlockedScriptRunners->Count() &&
+    NS_ASSERTION(lastBlocker == sLayoutRoots->sBlockedScriptRunners.Count() &&
                  sRunnersCountAtFirstBlocker == 0,
                  "Bad count");
     NS_ASSERTION(!sScriptBlockerCount, "This is really bad");
@@ -4165,7 +4189,7 @@ nsContentUtils::AddScriptRunner(nsIRunna
   }
 
   if (sScriptBlockerCount) {
-    return sBlockedScriptRunners->AppendObject(aRunnable);
+    return sLayoutRoots->sBlockedScriptRunners.AppendObject(aRunnable);
   }
   
   nsCOMPtr<nsIRunnable> run = aRunnable;
@@ -4196,19 +4220,12 @@ nsContentUtils::URIIsLocalFile(nsIURI *a
 nsContentUtils::URIIsLocalFile(nsIURI *aURI)
 {
   PRBool isFile;
-  nsCOMPtr<nsINetUtil> util = do_QueryInterface(sIOService);
+  nsCOMPtr<nsINetUtil> util = do_QueryInterface(sLayoutRoots->sIOService);
 
   return util && NS_SUCCEEDED(util->ProtocolHasFlags(aURI,
                                 nsIProtocolHandler::URI_IS_LOCAL_FILE,
                                 &isFile)) &&
          isFile;
-}
-
-/* static */
-void
-nsAutoGCRoot::Shutdown()
-{
-  NS_IF_RELEASE(sJSRuntimeService);
 }
 
 nsIAtom*
diff --git a/content/html/content/src/nsHTMLInputElement.cpp b/content/html/content/src/nsHTMLInputElement.cpp
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -145,7 +145,8 @@ static NS_DEFINE_CID(kXULControllersCID,
 
 static const char kWhitespace[] = "\n\r\t\b";
 
-class nsHTMLInputElement : public nsGenericHTMLFormElement,
+class nsHTMLInputElement : public XPCOMGCFinalizedObject,
+                           public nsGenericHTMLFormElement,
                            public nsImageLoadingContent,
                            public nsIDOMHTMLInputElement,
                            public nsIDOMNSHTMLInputElement,
@@ -438,7 +439,7 @@ nsHTMLInputElement::Clone(nsINodeInfo *a
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  nsCOMPtr<nsINode> kungFuDeathGrip = it;
+  nsINode* kungFuDeathGrip = it;
   nsresult rv = CopyInnerTo(it);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -475,7 +476,7 @@ nsHTMLInputElement::Clone(nsINodeInfo *a
       break;
   }
 
-  kungFuDeathGrip.swap(*aResult);
+  swap(kungFuDeathGrip, *aResult);
 
   return NS_OK;
 }
@@ -756,8 +757,8 @@ nsHTMLInputElement::GetValue(nsAString& 
       }
     } else {
       // Just return the leaf name
-      nsCOMPtr<nsIFile> file;
-      GetFile(getter_AddRefs(file));
+      nsIFile* file = nsnull;
+      GetFile(&file);
       if (!file || NS_FAILED(file->GetLeafName(aValue))) {
         aValue.Truncate();
       }
@@ -879,9 +880,9 @@ nsHTMLInputElement::GetFile(nsIFile** aF
 
   if (!(*aFile)) {
     // this is no "file://", try as local file
-    nsCOMPtr<nsILocalFile> localFile;
-    rv = NS_NewLocalFile(*mFileName, PR_FALSE, getter_AddRefs(localFile));
-    NS_IF_ADDREF(*aFile = localFile);
+    nsILocalFile* localFile = nsnull;
+    rv = NS_NewLocalFile(*mFileName, PR_FALSE, &localFile);
+    *aFile = localFile;
   }
 
   return rv;
@@ -894,11 +895,11 @@ nsHTMLInputElement::UpdateFileList()
     mFileList->Clear();
 
     if (mType == NS_FORM_INPUT_FILE && mFileName) {
-      nsCOMPtr<nsIFile> file;
-      nsresult rv = GetFile(getter_AddRefs(file));
+      nsIFile* file = nsnull;
+      nsresult rv = GetFile(&file);
       NS_ENSURE_SUCCESS(rv, rv);
 
-      nsRefPtr<nsDOMFile> domFile = new nsDOMFile(file);
+      nsDOMFile* domFile = new nsDOMFile(file);
       if (domFile) {
         if (!mFileList->Append(domFile)) {
           return NS_ERROR_FAILURE;
@@ -1008,9 +1009,9 @@ nsHTMLInputElement::DoSetCheckedChanged(
 {
   if (mType == NS_FORM_INPUT_RADIO) {
     if (GET_BOOLBIT(mBitField, BF_CHECKED_CHANGED) != aCheckedChanged) {
-      nsCOMPtr<nsIRadioVisitor> visitor;
+      nsIRadioVisitor* visitor = nsnull;
       NS_GetRadioSetCheckedChangedVisitor(aCheckedChanged,
-                                          getter_AddRefs(visitor));
+                                          &visitor);
       VisitGroup(visitor, aNotify);
     }
   } else {
@@ -1074,7 +1075,7 @@ nsHTMLInputElement::DoSetChecked(PRBool 
       rv = RadioSetChecked(aNotify);
     } else {
       rv = SetCheckedInternal(PR_FALSE, aNotify);
-      nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
+      nsIRadioGroupContainer* container = GetRadioGroupContainer();
       if (container) {
         nsAutoString name;
         if (GetNameIfExists(name)) {
@@ -1097,15 +1098,15 @@ nsHTMLInputElement::RadioSetChecked(PRBo
   //
   // Find the selected radio button so we can deselect it
   //
-  nsCOMPtr<nsIDOMHTMLInputElement> currentlySelected;
-  nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
+  nsIDOMHTMLInputElement* currentlySelected = nsnull;
+  nsIRadioGroupContainer* container = GetRadioGroupContainer();
   // This is ONLY INITIALIZED IF container EXISTS
   nsAutoString name;
   PRBool nameExists = PR_FALSE;
   if (container) {
     nameExists = GetNameIfExists(name);
     if (nameExists) {
-      container->GetCurrentRadioButton(name, getter_AddRefs(currentlySelected));
+      container->GetCurrentRadioButton(name, &currentlySelected);
     }
   }
 
@@ -1160,7 +1161,7 @@ nsHTMLInputElement::MaybeSubmitForm(nsPr
     return NS_OK;
   }
   
-  nsCOMPtr<nsIPresShell> shell = aPresContext->GetPresShell();
+  nsIPresShell* shell = aPresContext->GetPresShell();
   if (!shell) {
     return NS_OK;
   }
@@ -1168,7 +1169,7 @@ nsHTMLInputElement::MaybeSubmitForm(nsPr
   // Get the default submit element
   nsIFormControl* submitControl = mForm->GetDefaultSubmitElement();
   if (submitControl) {
-    nsCOMPtr<nsIContent> submitContent(do_QueryInterface(submitControl));
+    nsIContent* submitContent(do_QueryInterface(submitControl));
     NS_ASSERTION(submitContent, "Form control not implementing nsIContent?!");
     // Fire the button's onclick handler and let the button handle
     // submitting the form.
@@ -1177,7 +1178,7 @@ nsHTMLInputElement::MaybeSubmitForm(nsPr
     shell->HandleDOMEventWithTarget(submitContent, &event, &status);
   } else if (mForm->HasSingleTextControl()) {
     // If there's only one text control, just submit the form
-    nsCOMPtr<nsIContent> form = do_QueryInterface(mForm);
+    nsIContent* form = do_QueryInterface(mForm);
     nsFormEvent event(PR_TRUE, NS_FORM_SUBMIT);
     nsEventStatus status  = nsEventStatus_eIgnore;
     shell->HandleDOMEventWithTarget(form, &event, &status);
@@ -1238,7 +1239,7 @@ nsHTMLInputElement::FireOnChange()
   //
   nsEventStatus status = nsEventStatus_eIgnore;
   nsEvent event(PR_TRUE, NS_FORM_CHANGE);
-  nsCOMPtr<nsPresContext> presContext = GetPresContext();
+  nsPresContext* presContext = GetPresContext();
   nsEventDispatcher::Dispatch(static_cast<nsIContent*>(this), presContext,
                               &event, nsnull, &status);
 }
@@ -1282,7 +1283,7 @@ nsHTMLInputElement::SetFocus(nsPresConte
   // If the window is not active, do not allow the focus to bring the
   // window to the front.  We update the focus controller, but do
   // nothing else.
-  nsCOMPtr<nsPIDOMWindow> win = doc->GetWindow();
+  nsPIDOMWindow* win = doc->GetWindow();
   if (win) {
     nsIFocusController *focusController = win->GetRootFocusController();
     if (focusController) {
@@ -1318,7 +1319,7 @@ nsHTMLInputElement::Select()
     // XXX Bug?  We have to give the input focus before contents can be
     // selected
 
-    nsCOMPtr<nsPresContext> presContext = GetPresContext();
+    nsPresContext* presContext = GetPresContext();
 
     // If the window is not active, do not allow the select to bring the
     // window to the front.  We update the focus controller, but do
@@ -1420,7 +1421,7 @@ nsHTMLInputElement::Click()
       mType == NS_FORM_INPUT_IMAGE) {
 
     // Strong in case the event kills it
-    nsCOMPtr<nsIDocument> doc = GetCurrentDoc();
+    nsIDocument* doc = GetCurrentDoc();
     if (!doc) {
       return rv;
     }
@@ -1428,7 +1429,7 @@ nsHTMLInputElement::Click()
     nsIPresShell *shell = doc->GetPrimaryShell();
 
     if (shell) {
-      nsCOMPtr<nsPresContext> context = shell->GetPresContext();
+      nsPresContext* context = shell->GetPresContext();
 
       if (context) {
         // Click() is never called from native code, but it may be
@@ -1526,13 +1527,13 @@ nsHTMLInputElement::PreHandleEvent(nsEve
 
       case NS_FORM_INPUT_RADIO:
         {
-          nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
+          nsIRadioGroupContainer* container = GetRadioGroupContainer();
           if (container) {
             nsAutoString name;
             if (GetNameIfExists(name)) {
-              nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton;
+              nsIDOMHTMLInputElement* selectedRadioButton = nsnull;
               container->GetCurrentRadioButton(name,
-                                               getter_AddRefs(selectedRadioButton));
+                                               &selectedRadioButton);
               aVisitor.mItemData = selectedRadioButton;
             }
           }
@@ -1620,7 +1621,7 @@ nsHTMLInputElement::PostHandleEvent(nsEv
       NS_IS_MOUSE_LEFT_CLICK(aVisitor.mEvent)) {
     nsUIEvent actEvent(NS_IS_TRUSTED_EVENT(aVisitor.mEvent), NS_UI_ACTIVATE, 1);
 
-    nsCOMPtr<nsIPresShell> shell = aVisitor.mPresContext->GetPresShell();
+    nsIPresShell* shell = aVisitor.mPresContext->GetPresShell();
     if (shell) {
       nsEventStatus status = nsEventStatus_eIgnore;
       SET_BOOLBIT(mBitField, BF_IN_INTERNAL_ACTIVATE, PR_TRUE);
@@ -1659,7 +1660,7 @@ nsHTMLInputElement::PostHandleEvent(nsEv
       // if it was cancelled and a radio button, then set the old
       // selected btn to TRUE. if it is a checkbox then set it to its
       // original value
-      nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton =
+      nsIDOMHTMLInputElement* selectedRadioButton =
         do_QueryInterface(aVisitor.mItemData);
       if (selectedRadioButton) {
         selectedRadioButton->SetChecked(PR_TRUE);
@@ -1682,7 +1683,7 @@ nsHTMLInputElement::PostHandleEvent(nsEv
         FireEventForAccessibility(this, aVisitor.mPresContext,
                                   NS_LITERAL_STRING("RadioStateChange"));
         // Fire event for the previous selected radio.
-        nsCOMPtr<nsIDOMHTMLInputElement> previous =
+        nsIDOMHTMLInputElement* previous =
           do_QueryInterface(aVisitor.mItemData);
         if(previous) {
           FireEventForAccessibility(previous, aVisitor.mPresContext,
@@ -1758,14 +1759,14 @@ nsHTMLInputElement::PostHandleEvent(nsEv
               case NS_VK_DOWN:
               case NS_VK_RIGHT:
               // Arrow key pressed, focus+select prev/next radio button
-              nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
+              nsIRadioGroupContainer* container = GetRadioGroupContainer();
               if (container) {
                 nsAutoString name;
                 if (GetNameIfExists(name)) {
-                  nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton;
+                  nsIDOMHTMLInputElement* selectedRadioButton = nsnull;
                   container->GetNextRadioButton(name, isMovingBack, this,
-                                                getter_AddRefs(selectedRadioButton));
-                  nsCOMPtr<nsIContent> radioContent =
+                                                &selectedRadioButton);
+                  nsIContent* radioContent =
                     do_QueryInterface(selectedRadioButton);
                   if (radioContent) {
                     rv = selectedRadioButton->Focus();
@@ -1811,7 +1812,7 @@ nsHTMLInputElement::PostHandleEvent(nsEv
             // If this is an enter on the button of a file input, don't submit
             // -- that's supposed to put up the filepicker
             if (mType == NS_FORM_INPUT_FILE) {
-              nsCOMPtr<nsIContent> maybeButton =
+              nsIContent* maybeButton =
                 do_QueryInterface(aVisitor.mEvent->originalTarget);
               if (maybeButton) {
                 isButton = maybeButton->AttrValueIs(kNameSpaceID_None,
@@ -1888,14 +1889,14 @@ nsHTMLInputElement::PostHandleEvent(nsEv
             event.originator      = this;
             nsEventStatus status  = nsEventStatus_eIgnore;
 
-            nsCOMPtr<nsIPresShell> presShell =
+            nsIPresShell* presShell =
               aVisitor.mPresContext->GetPresShell();
 
             // If |nsIPresShell::Destroy| has been called due to
             // handling the event the pres context will return a null
             // pres shell.  See bug 125624.
             if (presShell) {
-              nsCOMPtr<nsIContent> form(do_QueryInterface(mForm));
+              nsIContent* form(do_QueryInterface(mForm));
               presShell->HandleDOMEventWithTarget(form, &event, &status);
             }
           }
@@ -2160,7 +2161,7 @@ nsHTMLInputElement::GetControllers(nsICo
       mControllers = do_CreateInstance(kXULControllersCID, &rv);
       NS_ENSURE_SUCCESS(rv, rv);
 
-      nsCOMPtr<nsIController>
+      nsIController*
         controller(do_CreateInstance("@mozilla.org/editor/editorcontroller;1",
                                      &rv));
       NS_ENSURE_SUCCESS(rv, rv);
@@ -2170,7 +2171,6 @@ nsHTMLInputElement::GetControllers(nsICo
   }
 
   *aResult = mControllers;
-  NS_IF_ADDREF(*aResult);
 
   return NS_OK;
 }
@@ -2274,7 +2274,7 @@ nsHTMLInputElement::GetFiles(nsIDOMFileL
     UpdateFileList();
   }
 
-  NS_ADDREF(*aFileList = mFileList);
+  *aFileList = mFileList;
 
   return NS_OK;
 }
@@ -2304,7 +2304,7 @@ nsHTMLInputElement::GetPhonetic(nsAStrin
   nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
 
   if (formControlFrame) {
-    nsCOMPtr<nsIPhonetic>
+    nsIPhonetic*
       phonetic(do_QueryInterface(formControlFrame));
 
     if (phonetic)
@@ -2320,13 +2320,13 @@ FireEventForAccessibility(nsIDOMHTMLInpu
                           nsPresContext* aPresContext,
                           const nsAString& aEventType)
 {
-  nsCOMPtr<nsIDOMEvent> event;
+  nsIDOMEvent* event = nsnull;
   if (NS_SUCCEEDED(nsEventDispatcher::CreateEvent(aPresContext, nsnull,
                                                   NS_LITERAL_STRING("Events"),
-                                                  getter_AddRefs(event)))) {
+                                                  &event))) {
     event->InitEvent(aEventType, PR_TRUE, PR_TRUE);
 
-    nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
+    nsIPrivateDOMEvent* privateEvent(do_QueryInterface(event));
     if (privateEvent) {
       privateEvent->SetTrusted(PR_TRUE);
     }
@@ -2492,9 +2492,9 @@ nsHTMLInputElement::SubmitNamesValues(ns
     //
     // Open the file
     //
-    nsCOMPtr<nsIFile> file;
+    nsIFile* file = nsnull;
  
-    rv = GetFile(getter_AddRefs(file));
+    rv = GetFile(&file);
 
     if (file) {
 
@@ -2511,7 +2511,7 @@ nsHTMLInputElement::SubmitNamesValues(ns
           //
           // Get content type
           //
-          nsCOMPtr<nsIMIMEService> MIMEService =
+          nsIMIMEService* MIMEService =
             do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
           NS_ENSURE_SUCCESS(rv, rv);
 
@@ -2524,8 +2524,8 @@ nsHTMLInputElement::SubmitNamesValues(ns
           //
           // Get input stream
           //
-          nsCOMPtr<nsIInputStream> fileStream;
-          rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream),
+          nsIInputStream* fileStream = nsnull;
+          rv = NS_NewLocalFileInputStream(&fileStream,
                                           file, -1, -1,
                                           nsIFileInputStream::CLOSE_ON_EOF |
                                           nsIFileInputStream::REOPEN_ON_REWIND);
@@ -2533,8 +2533,8 @@ nsHTMLInputElement::SubmitNamesValues(ns
             //
             // Create buffered stream (for efficiency)
             //
-            nsCOMPtr<nsIInputStream> bufferedStream;
-            rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
+            nsIInputStream* bufferedStream = nsnull;
+            rv = NS_NewBufferedInputStream(&bufferedStream,
                                            fileStream, 8192);
             NS_ENSURE_SUCCESS(rv, rv);
             if (bufferedStream) {
@@ -2825,9 +2825,9 @@ nsHTMLInputElement::AddedToRadioGroup(PR
   // the same for this new element as for all the others in the group
   //
   PRBool checkedChanged = PR_FALSE;
-  nsCOMPtr<nsIRadioVisitor> visitor;
+  nsIRadioVisitor* visitor = nsnull;
   nsresult rv = NS_GetRadioGetCheckedChangedVisitor(&checkedChanged, this,
-                                           getter_AddRefs(visitor));
+                                           &visitor);
   NS_ENSURE_SUCCESS(rv, rv);
   
   VisitGroup(visitor, aNotify);
@@ -2836,7 +2836,7 @@ nsHTMLInputElement::AddedToRadioGroup(PR
   //
   // Add the radio to the radio group container.
   //
-  nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
+  nsIRadioGroupContainer* container = GetRadioGroupContainer();
   if (container) {
     nsAutoString name;
     if (GetNameIfExists(name)) {
@@ -2876,7 +2876,7 @@ nsHTMLInputElement::WillRemoveFromRadioG
       gotName = PR_TRUE;
     }
 
-    nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
+    nsIRadioGroupContainer* container = GetRadioGroupContainer();
     if (container) {
       container->SetCurrentRadioButton(name, nsnull);
     }
@@ -2885,7 +2885,7 @@ nsHTMLInputElement::WillRemoveFromRadioG
   //
   // Remove this radio from its group in the container
   //
-  nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
+  nsIRadioGroupContainer* container = GetRadioGroupContainer();
   if (container) {
     if (!gotName) {
       if (!GetNameIfExists(name)) {
@@ -2949,15 +2949,15 @@ nsHTMLInputElement::IsHTMLFocusable(PRBo
 
   // Current radio button is not selected.
   // But make it tabbable if nothing in group is selected.
-  nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
+  nsIRadioGroupContainer* container = GetRadioGroupContainer();
   nsAutoString name;
   if (!container || !GetNameIfExists(name)) {
     *aIsFocusable = PR_TRUE;
     return PR_FALSE;
   }
 
-  nsCOMPtr<nsIDOMHTMLInputElement> currentRadio;
-  container->GetCurrentRadioButton(name, getter_AddRefs(currentRadio));
+  nsIDOMHTMLInputElement* currentRadio = nsnull;
+  container->GetCurrentRadioButton(name, &currentRadio);
   if (currentRadio) {
     *aTabIndex = -1;
   }
@@ -2969,7 +2969,7 @@ nsHTMLInputElement::VisitGroup(nsIRadioV
 nsHTMLInputElement::VisitGroup(nsIRadioVisitor* aVisitor, PRBool aFlushContent)
 {
   nsresult rv = NS_OK;
-  nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
+  nsIRadioGroupContainer* container = GetRadioGroupContainer();
   if (container) {
     nsAutoString name;
     if (GetNameIfExists(name)) {
@@ -3010,7 +3010,7 @@ NS_IMPL_ISUPPORTS1(nsRadioVisitor, nsIRa
 //
 // CLASS nsRadioSetCheckedChangedVisitor
 //
-class nsRadioSetCheckedChangedVisitor : public nsRadioVisitor {
+class nsRadioSetCheckedChangedVisitor : public XPCOMGCFinalizedObject, public nsRadioVisitor {
 public:
   nsRadioSetCheckedChangedVisitor(PRBool aCheckedChanged) :
     nsRadioVisitor(), mCheckedChanged(aCheckedChanged)
@@ -3020,7 +3020,7 @@ public:
 
   NS_IMETHOD Visit(nsIFormControl* aRadio, PRBool* aStop)
   {
-    nsCOMPtr<nsIRadioControlElement> radio(do_QueryInterface(aRadio));
+    nsIRadioControlElement* radio(do_QueryInterface(aRadio));
     NS_ASSERTION(radio, "Visit() passed a null button (or non-radio)!");
     radio->SetCheckedChangedInternal(mCheckedChanged);
     return NS_OK;
@@ -3033,7 +3033,7 @@ protected:
 //
 // CLASS nsRadioGetCheckedChangedVisitor
 //
-class nsRadioGetCheckedChangedVisitor : public nsRadioVisitor {
+class nsRadioGetCheckedChangedVisitor : public XPCOMGCFinalizedObject, public nsRadioVisitor {
 public:
   nsRadioGetCheckedChangedVisitor(PRBool* aCheckedChanged,
                                   nsIFormControl* aExcludeElement) :
@@ -3049,7 +3049,7 @@ public:
     if (aRadio == mExcludeElement) {
       return NS_OK;
     }
-    nsCOMPtr<nsIRadioControlElement> radio(do_QueryInterface(aRadio));
+    nsIRadioControlElement* radio(do_QueryInterface(aRadio));
     NS_ASSERTION(radio, "Visit() passed a null button (or non-radio)!");
     radio->GetCheckedChanged(mCheckedChanged);
     *aStop = PR_TRUE;
@@ -3082,9 +3082,8 @@ NS_GetRadioSetCheckedChangedVisitor(PRBo
       if (!sVisitorTrue) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
-      NS_ADDREF(sVisitorTrue);
       nsresult rv =
-        nsContentUtils::ReleasePtrOnShutdown((nsISupports**)&sVisitorTrue);
+        nsContentUtils::RootUntilLayoutShutdown(sVisitorTrue);
       if (NS_FAILED(rv)) {
         NS_RELEASE(sVisitorTrue);
         return rv;
@@ -3101,9 +3100,8 @@ NS_GetRadioSetCheckedChangedVisitor(PRBo
       if (!sVisitorFalse) {
         return NS_ERROR_OUT_OF_MEMORY;
       }
-      NS_ADDREF(sVisitorFalse);
       nsresult rv =
-        nsContentUtils::ReleasePtrOnShutdown((nsISupports**)&sVisitorFalse);
+        nsContentUtils::RootUntilLayoutShutdown(sVisitorFalse);
       if (NS_FAILED(rv)) {
         NS_RELEASE(sVisitorFalse);
         return rv;
@@ -3112,7 +3110,6 @@ NS_GetRadioSetCheckedChangedVisitor(PRBo
     *aVisitor = sVisitorFalse;
   }
 
-  NS_ADDREF(*aVisitor);
   return NS_OK;
 }
 
@@ -3126,7 +3123,6 @@ NS_GetRadioGetCheckedChangedVisitor(PRBo
   if (!*aVisitor) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
-  NS_ADDREF(*aVisitor);
 
   return NS_OK;
 }