Bug 757485, remove nsIXBLService and use nsXBLService directly, r=bz
authorNeil Deakin <neil@mozilla.com>
Wed, 23 May 2012 14:46:04 -0400
changeset 98799 34c610d4e7998fd0341fe354fec75c1105705294
parent 98798 fb10831a58a5398c980c6ff4fb72faab8fd22311
child 98800 95e2e6a47831d16538e0e0ba7bef9eeee94eeaf7
push id1116
push userlsblakk@mozilla.com
push dateMon, 16 Jul 2012 19:38:18 +0000
treeherdermozilla-beta@95f959a8b4dc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs757485
milestone15.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 757485, remove nsIXBLService and use nsXBLService directly, r=bz
content/base/src/nsContentUtils.cpp
content/base/src/nsDocument.cpp
content/base/src/nsGenericElement.cpp
content/svg/content/src/nsSVGElement.cpp
content/xbl/Makefile.in
content/xbl/public/Makefile.in
content/xbl/public/nsIXBLService.h
content/xbl/src/nsBindingManager.cpp
content/xbl/src/nsXBLPrototypeBinding.h
content/xbl/src/nsXBLPrototypeResources.cpp
content/xbl/src/nsXBLResourceLoader.cpp
content/xbl/src/nsXBLService.cpp
content/xbl/src/nsXBLService.h
content/xbl/src/nsXBLWindowKeyHandler.cpp
content/xbl/src/nsXBLWindowKeyHandler.h
content/xul/content/src/nsXULElement.cpp
content/xul/content/src/nsXULElement.h
content/xul/document/src/nsXULDocument.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
layout/build/nsLayoutModule.cpp
layout/build/nsLayoutStatics.cpp
layout/xul/base/src/nsSplitterFrame.cpp
widget/cocoa/nsMenuX.mm
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -68,17 +68,16 @@
 #include "nsIImageLoadingContent.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsILoadGroup.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsContentPolicyUtils.h"
 #include "nsNodeInfoManager.h"
-#include "nsIXBLService.h"
 #include "nsCRT.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIPrivateDOMEvent.h"
 #ifdef MOZ_XTF
 #include "nsIXTFService.h"
 static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
 #endif
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -63,17 +63,16 @@
 
 #include "nsContentCID.h"
 #include "nsDOMError.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIJSON.h"
 #include "nsThreadUtils.h"
 #include "nsNodeInfoManager.h"
-#include "nsIXBLService.h"
 #include "nsIFileChannel.h"
 #include "nsIMultiPartChannel.h"
 #include "nsIRefreshURI.h"
 #include "nsIWebNavigation.h"
 #include "nsIScriptError.h"
 
 #include "nsNetUtil.h"     // for NS_MakeAbsoluteURI
 
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -60,17 +60,16 @@
 #include "nsFrameManager.h"
 #include "nsFrameSelection.h"
 #ifdef DEBUG
 #include "nsRange.h"
 #endif
 
 #include "nsBindingManager.h"
 #include "nsXBLBinding.h"
-#include "nsIXBLService.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIBoxObject.h"
 #include "nsClientRect.h"
 #include "nsSVGUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 #include "nsIJSContextStack.h"
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -16,17 +16,16 @@
 #include "nsMutationEvent.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsBindingManager.h"
 #include "nsXBLBinding.h"
 #include "nsStyleConsts.h"
 #include "nsDOMError.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
-#include "nsIXBLService.h"
 #include "nsGkAtoms.h"
 #include "mozilla/css/StyleRule.h"
 #include "nsRuleWalker.h"
 #include "mozilla/css/Declaration.h"
 #include "nsCSSProps.h"
 #include "nsCSSParser.h"
 #include "nsGenericHTMLElement.h"
 #include "nsNodeInfoManager.h"
--- a/content/xbl/Makefile.in
+++ b/content/xbl/Makefile.in
@@ -5,13 +5,13 @@
 
 DEPTH		= ../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-PARALLEL_DIRS	= public src builtin
+PARALLEL_DIRS	= src builtin
 
 TEST_DIRS += test
 
 include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/content/xbl/public/Makefile.in
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH           = ../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE		= content
-
-EXPORTS		= \
-	nsIXBLService.h \
-	$(NULL)
-
-include $(topsrcdir)/config/rules.mk
-
deleted file mode 100644
--- a/content/xbl/public/nsIXBLService.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
-
-  Private interface to the XBL service
-
-*/
-
-#ifndef nsIXBLService_h__
-#define nsIXBLService_h__
-
-#include "nsISupports.h"
-
-class nsIContent;
-class nsIDocument;
-class nsIDOMEventTarget;
-class nsIDOMNodeList;
-class nsXBLBinding;
-class nsXBLDocumentInfo;
-class nsIURI;
-class nsIAtom;
-class nsIPrincipal;
-
-#define NS_IXBLSERVICE_IID      \
-{ 0x8a25483c, 0x1ac6, 0x4796, { 0xa6, 0x12, 0x5a, 0xe0, 0x5c, 0x83, 0x65, 0x0b } }
-
-class nsIXBLService : public nsISupports
-{
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXBLSERVICE_IID)
-
-  // This function loads a particular XBL file and installs all of the bindings
-  // onto the element.  aOriginPrincipal must not be null here.
-  NS_IMETHOD LoadBindings(nsIContent* aContent, nsIURI* aURL,
-                          nsIPrincipal* aOriginPrincipal, bool aAugmentFlag,
-                          nsXBLBinding** aBinding, bool* aResolveStyle) = 0;
-
-  // Indicates whether or not a binding is fully loaded.
-  NS_IMETHOD BindingReady(nsIContent* aBoundElement, nsIURI* aURI, bool* aIsReady) = 0;
-
-  // Retrieves our base class (e.g., tells us what type of frame and content node to build)
-  NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult) = 0;
-
-  // This method checks the hashtable and then calls FetchBindingDocument on a
-  // miss.  aOriginPrincipal or aBoundDocument may be null to bypass security
-  // checks.
-  NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement,
-                                     nsIDocument* aBoundDocument,
-                                     nsIURI* aBindingURI,
-                                     nsIPrincipal* aOriginPrincipal,
-                                     bool aForceSyncLoad,
-                                     nsXBLDocumentInfo** aResult) = 0;
-
-  // Hooks up the global key event handlers to the document root.
-  NS_IMETHOD AttachGlobalKeyHandler(nsIDOMEventTarget* aTarget) = 0;
-  NS_IMETHOD DetachGlobalKeyHandler(nsIDOMEventTarget* aTarget) = 0;
-  
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIXBLService, NS_IXBLSERVICE_IID)
-
-#endif // nsIXBLService_h__
--- a/content/xbl/src/nsBindingManager.cpp
+++ b/content/xbl/src/nsBindingManager.cpp
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 sw=2 et tw=79: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCOMPtr.h"
-#include "nsIXBLService.h"
+#include "nsXBLService.h"
 #include "nsIInputStream.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsIChannel.h"
 #include "nsXPIDLString.h"
 #include "nsNetUtil.h"
 #include "plstr.h"
 #include "nsIContent.h"
@@ -840,21 +840,19 @@ nsBindingManager::GetSingleInsertionPoin
   return nsnull;
 }
 
 nsresult
 nsBindingManager::AddLayeredBinding(nsIContent* aContent, nsIURI* aURL,
                                     nsIPrincipal* aOriginPrincipal)
 {
   // First we need to load our binding.
-  nsresult rv;
-  nsCOMPtr<nsIXBLService> xblService = 
-           do_GetService("@mozilla.org/xbl;1", &rv);
+  nsXBLService* xblService = nsXBLService::GetInstance();
   if (!xblService)
-    return rv;
+    return NS_ERROR_FAILURE;
 
   // Load the bindings.
   nsRefPtr<nsXBLBinding> binding;
   bool dummy;
   xblService->LoadBindings(aContent, aURL, aOriginPrincipal, true,
                            getter_AddRefs(binding), &dummy);
   if (binding) {
     AddToAttachedQueue(binding);
@@ -915,21 +913,19 @@ nsBindingManager::RemoveLayeredBinding(n
 nsresult
 nsBindingManager::LoadBindingDocument(nsIDocument* aBoundDoc,
                                       nsIURI* aURL,
                                       nsIPrincipal* aOriginPrincipal)
 {
   NS_PRECONDITION(aURL, "Must have a URI to load!");
   
   // First we need to load our binding.
-  nsresult rv;
-  nsCOMPtr<nsIXBLService> xblService = 
-           do_GetService("@mozilla.org/xbl;1", &rv);
+  nsXBLService* xblService = nsXBLService::GetInstance();
   if (!xblService)
-    return rv;
+    return NS_ERROR_FAILURE;
 
   // Load the binding doc.
   nsRefPtr<nsXBLDocumentInfo> info;
   xblService->LoadBindingDocumentInfo(nsnull, aBoundDoc, aURL,
                                       aOriginPrincipal, true,
                                       getter_AddRefs(info));
   if (!info)
     return NS_ERROR_FAILURE;
--- a/content/xbl/src/nsXBLPrototypeBinding.h
+++ b/content/xbl/src/nsXBLPrototypeBinding.h
@@ -18,17 +18,16 @@
 #include "nsXBLDocumentInfo.h"
 #include "nsCOMArray.h"
 #include "nsXBLProtoImpl.h"
 
 class nsIAtom;
 class nsIDocument;
 class nsIScriptContext;
 class nsSupportsHashtable;
-class nsIXBLService;
 class nsFixedSizeAllocator;
 class nsXBLProtoImplField;
 class nsXBLBinding;
 class nsCSSStyleSheet;
 
 // This structure represents an insertion point, and is used when writing out
 // insertion points. It contains comparison operators so that it can be stored
 // in an array sorted by index.
--- a/content/xbl/src/nsXBLPrototypeResources.cpp
+++ b/content/xbl/src/nsXBLPrototypeResources.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIStyleRuleProcessor.h"
 #include "nsIDocument.h"
 #include "nsIContent.h"
-#include "nsIXBLService.h"
 #include "nsIServiceManager.h"
 #include "nsXBLResourceLoader.h"
 #include "nsXBLPrototypeResources.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsIDocumentObserver.h"
 #include "mozilla/css/Loader.h"
 #include "nsIURI.h"
 #include "nsLayoutCID.h"
--- a/content/xbl/src/nsXBLResourceLoader.cpp
+++ b/content/xbl/src/nsXBLResourceLoader.cpp
@@ -5,17 +5,17 @@
 
 #include "nsTArray.h"
 #include "nsString.h"
 #include "nsCSSStyleSheet.h"
 #include "nsIStyleRuleProcessor.h"
 #include "nsIDocument.h"
 #include "nsIContent.h"
 #include "nsIPresShell.h"
-#include "nsIXBLService.h"
+#include "nsXBLService.h"
 #include "nsIServiceManager.h"
 #include "nsXBLResourceLoader.h"
 #include "nsXBLPrototypeResources.h"
 #include "nsIDocumentObserver.h"
 #include "imgILoader.h"
 #include "imgIRequest.h"
 #include "mozilla/css/Loader.h"
 #include "nsIURI.h"
@@ -197,17 +197,20 @@ nsXBLResourceLoader::AddResourceListener
   if (aBoundElement) {
     mBoundElements.AppendObject(aBoundElement);
   }
 }
 
 void
 nsXBLResourceLoader::NotifyBoundElements()
 {
-  nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
+  nsXBLService* xblService = nsXBLService::GetInstance();
+  if (!xblService)
+    return;
+
   nsIURI* bindingURI = mBinding->BindingURI();
 
   PRUint32 eltCount = mBoundElements.Count();
   for (PRUint32 j = 0; j < eltCount; j++) {
     nsCOMPtr<nsIContent> content = mBoundElements.ObjectAt(j);
     
     bool ready = false;
     xblService->BindingReady(content, bindingURI, &ready);
--- a/content/xbl/src/nsXBLService.cpp
+++ b/content/xbl/src/nsXBLService.cpp
@@ -53,16 +53,18 @@
 #include "nsIDOMEventListener.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 
 #define NS_MAX_XBL_BINDING_RECURSION 20
 
+nsXBLService* nsXBLService::gInstance = nsnull;
+
 static bool
 IsAncestorBinding(nsIDocument* aDocument,
                   nsIURI* aChildBindingURI,
                   nsIContent* aChild)
 {
   NS_ASSERTION(aDocument, "expected a document");
   NS_ASSERTION(aChildBindingURI, "expected a binding URI");
   NS_ASSERTION(aChild, "expected a child content");
@@ -122,18 +124,17 @@ public:
     // We only need the document here to cause frame construction, so
     // we need the current doc, not the owner doc.
     nsIDocument* doc = mBoundElement->GetCurrentDoc();
     if (!doc)
       return;
 
     // Get the binding.
     bool ready = false;
-    gXBLService->BindingReady(mBoundElement, mBindingURI, &ready);
-
+    nsXBLService::GetInstance()->BindingReady(mBoundElement, mBindingURI, &ready);
     if (!ready)
       return;
 
     // If |mBoundElement| is (in addition to having binding |mBinding|)
     // also a descendant of another element with binding |mBinding|,
     // then we might have just constructed it due to the
     // notification of its parent.  (We can know about both if the
     // binding loads were triggered from the DOM rather than frame
@@ -151,36 +152,21 @@ public:
 
         if (!sc) {
           shell->RecreateFramesFor(mBoundElement);
         }
       }
     }
   }
 
-  static nsIXBLService* gXBLService;
-  static int gRefCnt;
-
 protected:
   nsXBLBindingRequest(nsIURI* aURI, nsIContent* aBoundElement)
     : mBindingURI(aURI),
       mBoundElement(aBoundElement)
   {
-    gRefCnt++;
-    if (gRefCnt == 1) {
-      CallGetService("@mozilla.org/xbl;1", &gXBLService);
-    }
-  }
-
-  ~nsXBLBindingRequest()
-  {
-    gRefCnt--;
-    if (gRefCnt == 0) {
-      NS_IF_RELEASE(gXBLService);
-    }
   }
 
 private:
   // Hide so that only Create() and Destroy() can be used to
   // allocate and deallocate from the heap
   static void* operator new(size_t) CPP_THROW_NEW { return 0; }
   static void operator delete(void*, size_t) {}
 };
@@ -188,72 +174,64 @@ private:
 static const size_t kBucketSizes[] = {
   sizeof(nsXBLBindingRequest)
 };
 
 static const PRInt32 kNumBuckets = sizeof(kBucketSizes)/sizeof(size_t);
 static const PRInt32 kNumElements = 64;
 static const PRInt32 kInitialSize = sizeof(nsXBLBindingRequest) * kNumElements;
 
-nsIXBLService* nsXBLBindingRequest::gXBLService = nsnull;
-int nsXBLBindingRequest::gRefCnt = 0;
-
 // nsXBLStreamListener, a helper class used for 
 // asynchronous parsing of URLs
 /* Header file */
 class nsXBLStreamListener : public nsIStreamListener, public nsIDOMEventListener
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSIDOMEVENTLISTENER
 
-  nsXBLStreamListener(nsXBLService* aXBLService,
-                      nsIDocument* aBoundDocument,
+  nsXBLStreamListener(nsIDocument* aBoundDocument,
                       nsIXMLContentSink* aSink,
                       nsIDocument* aBindingDocument);
   ~nsXBLStreamListener();
 
   void AddRequest(nsXBLBindingRequest* aRequest) { mBindingRequests.AppendElement(aRequest); }
   bool HasRequest(nsIURI* aURI, nsIContent* aBoundElement);
 
 private:
-  nsXBLService* mXBLService; // [WEAK]
-
   nsCOMPtr<nsIStreamListener> mInner;
   nsAutoTArray<nsXBLBindingRequest*, 8> mBindingRequests;
   
   nsCOMPtr<nsIWeakReference> mBoundDocument;
   nsCOMPtr<nsIXMLContentSink> mSink; // Only set until OnStartRequest
   nsCOMPtr<nsIDocument> mBindingDocument; // Only set until OnStartRequest
 };
 
 /* Implementation file */
 NS_IMPL_ISUPPORTS3(nsXBLStreamListener,
                    nsIStreamListener,
                    nsIRequestObserver,
                    nsIDOMEventListener)
 
-nsXBLStreamListener::nsXBLStreamListener(nsXBLService* aXBLService,
-                                         nsIDocument* aBoundDocument,
+nsXBLStreamListener::nsXBLStreamListener(nsIDocument* aBoundDocument,
                                          nsIXMLContentSink* aSink,
                                          nsIDocument* aBindingDocument)
 : mSink(aSink), mBindingDocument(aBindingDocument)
 {
   /* member initializers and constructor code */
-  mXBLService = aXBLService;
   mBoundDocument = do_GetWeakReference(aBoundDocument);
 }
 
 nsXBLStreamListener::~nsXBLStreamListener()
 {
   for (PRUint32 i = 0; i < mBindingRequests.Length(); i++) {
     nsXBLBindingRequest* req = mBindingRequests.ElementAt(i);
-    nsXBLBindingRequest::Destroy(mXBLService->mPool, req);
+    nsXBLBindingRequest::Destroy(nsXBLService::GetInstance()->mPool, req);
   }
 }
 
 NS_IMETHODIMP
 nsXBLStreamListener::OnDataAvailable(nsIRequest *request, nsISupports* aCtxt, nsIInputStream* aInStr, 
                                      PRUint32 aSourceOffset, PRUint32 aCount)
 {
   if (mInner)
@@ -407,58 +385,64 @@ nsXBLStreamListener::HandleEvent(nsIDOME
   target->RemoveEventListener(NS_LITERAL_STRING("load"), this, false);
 
   return rv;
 }
 
 // Implementation /////////////////////////////////////////////////////////////////
 
 // Static member variable initialization
-PRUint32 nsXBLService::gRefCnt = 0;
 bool nsXBLService::gAllowDataURIs = false;
 
 nsHashtable* nsXBLService::gClassTable = nsnull;
 
 JSCList  nsXBLService::gClassLRUList = JS_INIT_STATIC_CLIST(&nsXBLService::gClassLRUList);
 PRUint32 nsXBLService::gClassLRUListLength = 0;
 PRUint32 nsXBLService::gClassLRUListQuota = 64;
 
 // Implement our nsISupports methods
-NS_IMPL_ISUPPORTS3(nsXBLService, nsIXBLService, nsIObserver, nsISupportsWeakReference)
+NS_IMPL_ISUPPORTS2(nsXBLService, nsIObserver, nsISupportsWeakReference)
+
+void
+nsXBLService::Init()
+{
+  gInstance = new nsXBLService();
+  NS_ADDREF(gInstance);
+
+  // Register the first (and only) nsXBLService as a memory pressure observer
+  // so it can flush the LRU list in low-memory situations.
+  nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+  if (os)
+    os->AddObserver(gInstance, "memory-pressure", true);
+}
 
 // Constructors/Destructors
 nsXBLService::nsXBLService(void)
 {
   mPool.Init("XBL Binding Requests", kBucketSizes, kNumBuckets, kInitialSize);
 
-  gRefCnt++;
-  if (gRefCnt == 1) {
-    gClassTable = new nsHashtable();
-  }
+  gClassTable = new nsHashtable();
 
   Preferences::AddBoolVarCache(&gAllowDataURIs, "layout.debug.enable_data_xbl");
 }
 
 nsXBLService::~nsXBLService(void)
 {
-  gRefCnt--;
-  if (gRefCnt == 0) {
-    // Walk the LRU list removing and deleting the nsXBLJSClasses.
-    FlushMemory();
+  // Walk the LRU list removing and deleting the nsXBLJSClasses.
+  FlushMemory();
 
-    // Any straggling nsXBLJSClass instances held by unfinalized JS objects
-    // created for bindings will be deleted when those objects are finalized
-    // (and not put on gClassLRUList, because length >= quota).
-    gClassLRUListLength = gClassLRUListQuota = 0;
+  // Any straggling nsXBLJSClass instances held by unfinalized JS objects
+  // created for bindings will be deleted when those objects are finalized
+  // (and not put on gClassLRUList, because length >= quota).
+  gClassLRUListLength = gClassLRUListQuota = 0;
 
-    // At this point, the only hash table entries should be for referenced
-    // XBL class structs held by unfinalized JS binding objects.
-    delete gClassTable;
-    gClassTable = nsnull;
-  }
+  // At this point, the only hash table entries should be for referenced
+  // XBL class structs held by unfinalized JS binding objects.
+  delete gClassTable;
+  gClassTable = nsnull;
 }
 
 // static
 bool
 nsXBLService::IsChromeOrResourceURI(nsIURI* aURI)
 {
   bool isChrome = false;
   bool isResource = false;
@@ -466,17 +450,17 @@ nsXBLService::IsChromeOrResourceURI(nsIU
       NS_SUCCEEDED(aURI->SchemeIs("resource", &isResource)))
       return (isChrome || isResource);
   return false;
 }
 
 
 // This function loads a particular XBL file and installs all of the bindings
 // onto the element.
-NS_IMETHODIMP
+nsresult
 nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL,
                            nsIPrincipal* aOriginPrincipal, bool aAugmentFlag,
                            nsXBLBinding** aBinding, bool* aResolveStyle) 
 {
   NS_PRECONDITION(aOriginPrincipal, "Must have an origin principal");
   
   *aBinding = nsnull;
   *aResolveStyle = false;
@@ -605,36 +589,24 @@ nsXBLService::FlushStyleBindings(nsICont
 
     if (styleBinding == binding) 
       bindingManager->SetBinding(aContent, nsnull); // Flush old style bindings
   }
    
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsXBLService::ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID,
-                         nsIAtom** aResult)
-{
-  nsIDocument* document = aContent->OwnerDoc();
-  *aResult = document->BindingManager()->ResolveTag(aContent, aNameSpaceID);
-  NS_IF_ADDREF(*aResult);
-
-  return NS_OK;
-}
-
-
 //
 // AttachGlobalKeyHandler
 //
 // Creates a new key handler and prepares to listen to key events on the given
 // event receiver (either a document or an content node). If the receiver is content,
 // then extra work needs to be done to hook it up to the document (XXX WHY??)
 //
-NS_IMETHODIMP
+nsresult
 nsXBLService::AttachGlobalKeyHandler(nsIDOMEventTarget* aTarget)
 {
   // check if the receiver is a content node (not a document), and hook
   // it to the document if that is the case.
   nsCOMPtr<nsIDOMEventTarget> piTarget = aTarget;
   nsCOMPtr<nsIContent> contentNode(do_QueryInterface(aTarget));
   if (contentNode) {
     // Only attach if we're really in a document
@@ -681,17 +653,17 @@ nsXBLService::AttachGlobalKeyHandler(nsI
   return NS_OK;
 }
 
 //
 // DetachGlobalKeyHandler
 //
 // Removes a key handler added by DeatchGlobalKeyHandler.
 //
-NS_IMETHODIMP
+nsresult
 nsXBLService::DetachGlobalKeyHandler(nsIDOMEventTarget* aTarget)
 {
   nsCOMPtr<nsIDOMEventTarget> piTarget = aTarget;
   nsCOMPtr<nsIContent> contentNode(do_QueryInterface(aTarget));
   if (!contentNode) // detaching is only supported for content nodes
     return NS_ERROR_FAILURE;
 
   // Only attach if we're really in a document
@@ -744,19 +716,20 @@ nsXBLService::FlushMemory()
     delete c;
     gClassLRUListLength--;
   }
   return NS_OK;
 }
 
 // Internal helper methods ////////////////////////////////////////////////////////////////
 
-NS_IMETHODIMP nsXBLService::BindingReady(nsIContent* aBoundElement, 
-                                         nsIURI* aURI, 
-                                         bool* aIsReady)
+nsresult
+nsXBLService::BindingReady(nsIContent* aBoundElement,
+                           nsIURI* aURI, 
+                           bool* aIsReady)
 {
   // Don't do a security check here; we know this binding is set to go.
   return GetBinding(aBoundElement, aURI, true, nsnull, aIsReady, nsnull);
 }
 
 nsresult
 nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI, 
                          bool aPeekOnly, nsIPrincipal* aOriginPrincipal,
@@ -916,17 +889,17 @@ IsSystemOrChromeURLPrincipal(nsIPrincipa
   nsCOMPtr<nsIURI> uri;
   aPrincipal->GetURI(getter_AddRefs(uri));
   NS_ENSURE_TRUE(uri, false);
   
   bool isChrome = false;
   return NS_SUCCEEDED(uri->SchemeIs("chrome", &isChrome)) && isChrome;
 }
 
-NS_IMETHODIMP
+nsresult
 nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement,
                                       nsIDocument* aBoundDocument,
                                       nsIURI* aBindingURI,
                                       nsIPrincipal* aOriginPrincipal,
                                       bool aForceSyncLoad,
                                       nsXBLDocumentInfo** aResult)
 {
   NS_PRECONDITION(aBindingURI, "Must have a binding URI");
@@ -1125,17 +1098,17 @@ nsXBLService::FetchBindingDocument(nsICo
   nsCOMPtr<nsIInterfaceRequestor> sameOriginChecker = nsContentUtils::GetSameOriginChecker();
   NS_ENSURE_TRUE(sameOriginChecker, NS_ERROR_OUT_OF_MEMORY);
 
   channel->SetNotificationCallbacks(sameOriginChecker);
 
   if (!aForceSyncLoad) {
     // We can be asynchronous
     nsXBLStreamListener* xblListener =
-      new nsXBLStreamListener(this, aBoundDocument, xblSink, doc);
+      new nsXBLStreamListener(aBoundDocument, xblSink, doc);
     NS_ENSURE_TRUE(xblListener,NS_ERROR_OUT_OF_MEMORY);
 
     // Add ourselves to the list of loading docs.
     nsBindingManager *bindingManager;
     if (aBoundDocument)
       bindingManager = aBoundDocument->BindingManager();
     else
       bindingManager = nsnull;
@@ -1178,30 +1151,8 @@ nsXBLService::FetchBindingDocument(nsICo
   rv = nsSyncLoadService::PushSyncStreamToListener(in, listener, channel);
   NS_ENSURE_SUCCESS(rv, rv);
 
   doc.swap(*aResult);
 
   return NS_OK;
 }
 
-// Creation Routine ///////////////////////////////////////////////////////////////////////
-
-nsresult NS_NewXBLService(nsIXBLService** aResult);
-
-nsresult
-NS_NewXBLService(nsIXBLService** aResult)
-{
-  nsXBLService* result = new nsXBLService;
-  if (! result)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*aResult = result);
-
-  // Register the first (and only) nsXBLService as a memory pressure observer
-  // so it can flush the LRU list in low-memory situations.
-  nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
-  if (os)
-    os->AddObserver(result, "memory-pressure", true);
-
-  return NS_OK;
-}
-
--- a/content/xbl/src/nsXBLService.h
+++ b/content/xbl/src/nsXBLService.h
@@ -1,70 +1,77 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-#include "nsIXBLService.h"
+#include "nsString.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
 #include "jsapi.h"              // nsXBLJSClass derives from JSClass
 #include "jsclist.h"            // nsXBLJSClass derives from JSCList
 #include "nsFixedSizeAllocator.h"
 #include "nsTArray.h"
 
 class nsXBLBinding;
 class nsXBLDocumentInfo;
 class nsIContent;
 class nsIDocument;
-class nsIAtom;
 class nsString;
 class nsIURI;
+class nsIPrincipal;
 class nsSupportsHashtable;
 class nsHashtable;
+class nsIDOMEventTarget;
 
-class nsXBLService : public nsIXBLService,
-                     public nsIObserver,
+class nsXBLService : public nsIObserver,
                      public nsSupportsWeakReference
 {
   NS_DECL_ISUPPORTS
 
+  static nsXBLService* gInstance;
+
+  static void Init();
+
+  static void Shutdown() {
+    NS_IF_RELEASE(gInstance);
+  }
+
+  static nsXBLService* GetInstance() { return gInstance; }
+
   static bool IsChromeOrResourceURI(nsIURI* aURI);
 
   // This function loads a particular XBL file and installs all of the bindings
   // onto the element.  aOriginPrincipal must not be null here.
-  NS_IMETHOD LoadBindings(nsIContent* aContent, nsIURI* aURL,
-                          nsIPrincipal* aOriginPrincipal, bool aAugmentFlag,
-                          nsXBLBinding** aBinding, bool* aResolveStyle);
+  nsresult LoadBindings(nsIContent* aContent, nsIURI* aURL,
+                        nsIPrincipal* aOriginPrincipal, bool aAugmentFlag,
+                        nsXBLBinding** aBinding, bool* aResolveStyle);
 
   // Indicates whether or not a binding is fully loaded.
-  NS_IMETHOD BindingReady(nsIContent* aBoundElement, nsIURI* aURI, bool* aIsReady);
-
-  // Gets the object's base class type.
-  NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult);
+  nsresult BindingReady(nsIContent* aBoundElement, nsIURI* aURI, bool* aIsReady);
 
   // This method checks the hashtable and then calls FetchBindingDocument on a
   // miss.  aOriginPrincipal or aBoundDocument may be null to bypass security
   // checks.
-  NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement,
-                                     nsIDocument* aBoundDocument,
-                                     nsIURI* aBindingURI,
-                                     nsIPrincipal* aOriginPrincipal,
-                                     bool aForceSyncLoad,
-                                     nsXBLDocumentInfo** aResult);
+  nsresult LoadBindingDocumentInfo(nsIContent* aBoundElement,
+                                   nsIDocument* aBoundDocument,
+                                   nsIURI* aBindingURI,
+                                   nsIPrincipal* aOriginPrincipal,
+                                   bool aForceSyncLoad,
+                                   nsXBLDocumentInfo** aResult);
 
   // Used by XUL key bindings and for window XBL.
-  NS_IMETHOD AttachGlobalKeyHandler(nsIDOMEventTarget* aTarget);
-  NS_IMETHOD DetachGlobalKeyHandler(nsIDOMEventTarget* aTarget);
+  static nsresult AttachGlobalKeyHandler(nsIDOMEventTarget* aTarget);
+  static nsresult DetachGlobalKeyHandler(nsIDOMEventTarget* aTarget);
 
   NS_DECL_NSIOBSERVER
 
-public:
+private:
   nsXBLService();
   virtual ~nsXBLService();
 
 protected:
   // This function clears out the bindings on a given content node.
   nsresult FlushStyleBindings(nsIContent* aContent);
 
   // Release any memory that we can
@@ -101,18 +108,16 @@ protected:
    */
   nsresult GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
                       bool aPeekFlag, nsIPrincipal* aOriginPrincipal,
                       bool* aIsReady, nsXBLBinding** aResult,
                       nsTArray<nsIURI*>& aDontExtendURIs);
 
 // MEMBER VARIABLES
 public:
-  static PRUint32 gRefCnt;                   // A count of XBLservice instances.
-
   static bool gDisableChromeCache;
 
   static nsHashtable* gClassTable;           // A table of nsXBLJSClass objects.
 
   static JSCList  gClassLRUList;             // LRU list of cached classes.
   static PRUint32 gClassLRUListLength;       // Number of classes on LRU list.
   static PRUint32 gClassLRUListQuota;        // Quota on class LRU list.
   static bool     gAllowDataURIs;            // Whether we should allow data
--- a/content/xbl/src/nsXBLWindowKeyHandler.cpp
+++ b/content/xbl/src/nsXBLWindowKeyHandler.cpp
@@ -66,20 +66,18 @@ const char nsXBLSpecialDocInfo::sHTMLBin
   "chrome://global/content/platformHTMLBindings.xml";
 
 void nsXBLSpecialDocInfo::LoadDocInfo()
 {
   if (mInitialized)
     return;
   mInitialized = true;
 
-  nsresult rv;
-  nsCOMPtr<nsIXBLService> xblService = 
-           do_GetService("@mozilla.org/xbl;1", &rv);
-  if (NS_FAILED(rv) || !xblService)
+  nsXBLService* xblService = nsXBLService::GetInstance();
+  if (!xblService)
     return;
 
   // Obtain the platform doc info
   nsCOMPtr<nsIURI> bindingURI;
   NS_NewURI(getter_AddRefs(bindingURI), sHTMLBindingStr);
   if (!bindingURI) {
     return;
   }
--- a/content/xbl/src/nsXBLWindowKeyHandler.h
+++ b/content/xbl/src/nsXBLWindowKeyHandler.h
@@ -9,17 +9,16 @@
 #include "nsWeakPtr.h"
 #include "nsIDOMEventListener.h"
 
 class nsIAtom;
 class nsIDOMElement;
 class nsIDOMEventTarget;
 class nsIDOMKeyEvent;
 class nsIDOMEventTarget;
-class nsIXBLDocumentInfo;
 class nsXBLSpecialDocInfo;
 class nsXBLPrototypeHandler;
 
 class nsXBLWindowKeyHandler : public nsIDOMEventListener
 {
 public:
   nsXBLWindowKeyHandler(nsIDOMElement* aElement, nsIDOMEventTarget* aTarget);
   virtual ~nsXBLWindowKeyHandler();
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -54,17 +54,16 @@
 #include "nsIServiceManager.h"
 #include "mozilla/css/StyleRule.h"
 #include "nsIStyleSheet.h"
 #include "nsIURL.h"
 #include "nsIViewManager.h"
 #include "nsIWidget.h"
 #include "nsIXULDocument.h"
 #include "nsIXULTemplateBuilder.h"
-#include "nsIXBLService.h"
 #include "nsLayoutCID.h"
 #include "nsContentCID.h"
 #include "nsRDFCID.h"
 #include "nsStyleConsts.h"
 #include "nsXPIDLString.h"
 #include "nsXULControllers.h"
 #include "nsIBoxObject.h"
 #include "nsPIBoxObject.h"
@@ -100,19 +99,16 @@
 #include "nsEventDispatcher.h"
 #include "mozAutoDocUpdate.h"
 #include "nsIDOMXULCommandEvent.h"
 #include "nsIDOMNSEvent.h"
 #include "nsCCUncollectableMarker.h"
 
 namespace css = mozilla::css;
 
-// Global object maintenance
-nsIXBLService * nsXULElement::gXBLService = nsnull;
-
 /**
  * A tearoff class for nsXULElement to implement nsIScriptEventHandlerOwner.
  */
 class nsScriptEventHandlerOwnerTearoff : public nsIScriptEventHandlerOwner
 {
 public:
     nsScriptEventHandlerOwnerTearoff(nsXULElement* aElement)
     : mElement(aElement) {}
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -25,17 +25,16 @@
 #include "nsEventListenerManager.h"
 #include "nsIRDFCompositeDataSource.h"
 #include "nsIRDFResource.h"
 #include "nsIScriptObjectOwner.h"
 #include "nsBindingManager.h"
 #include "nsIURI.h"
 #include "nsIXULTemplateBuilder.h"
 #include "nsIBoxObject.h"
-#include "nsIXBLService.h"
 #include "nsLayoutCID.h"
 #include "nsAttrAndChildArray.h"
 #include "nsGkAtoms.h"
 #include "nsAutoPtr.h"
 #include "nsStyledElement.h"
 #include "nsDOMScriptObjectHolder.h"
 #include "nsIFrameLoader.h"
 #include "jspubtd.h"
@@ -385,30 +384,16 @@ public:
     static nsXULElement* FromContent(nsIContent *aContent)
     {
         if (aContent->IsXUL())
             return static_cast<nsXULElement*>(aContent);
         return nsnull;
     }
 
 public:
-    static nsIXBLService* GetXBLService() {
-        if (!gXBLService)
-            CallGetService("@mozilla.org/xbl;1", &gXBLService);
-        return gXBLService;
-    }
-    static void ReleaseGlobals() {
-        NS_IF_RELEASE(gXBLService);
-    }
-
-protected:
-    // pseudo-constants
-    static nsIXBLService*       gXBLService;
-
-public:
     nsXULElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
     static nsresult
     Create(nsXULPrototypeElement* aPrototype, nsIDocument* aDocument,
            bool aIsScriptable, mozilla::dom::Element** aResult);
 
     // nsISupports
     NS_DECL_ISUPPORTS_INHERITED
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -55,17 +55,17 @@
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsXULCommandDispatcher.h"
 #include "nsXULElement.h"
 #include "prlog.h"
 #include "rdf.h"
 #include "nsIFrame.h"
 #include "mozilla/FunctionTimer.h"
-#include "nsIXBLService.h"
+#include "nsXBLService.h"
 #include "nsCExternalHandlerService.h"
 #include "nsMimeTypes.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsContentList.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptGlobalObjectOwner.h"
 #include "nsIScriptRuntime.h"
@@ -1694,20 +1694,17 @@ nsXULDocument::AddElementToDocumentPre(E
 }
 
 nsresult
 nsXULDocument::AddElementToDocumentPost(Element* aElement)
 {
     // We need to pay special attention to the keyset tag to set up a listener
     if (aElement->NodeInfo()->Equals(nsGkAtoms::keyset, kNameSpaceID_XUL)) {
         // Create our XUL key listener and hook it up.
-        nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
-        if (xblService) {
-            xblService->AttachGlobalKeyHandler(aElement);
-        }
+        nsXBLService::AttachGlobalKeyHandler(aElement);
     }
 
     // See if we need to attach a XUL template to this node
     bool needsHookup;
     nsresult rv = CheckTemplateBuilderHookup(aElement, &needsHookup);
     if (NS_FAILED(rv))
         return rv;
 
@@ -1770,20 +1767,17 @@ nsXULDocument::RemoveSubtreeFromDocument
 
     Element* aElement = aContent->AsElement();
 
     // Do a bunch of cleanup to remove an element from the XUL
     // document.
     nsresult rv;
 
     if (aElement->NodeInfo()->Equals(nsGkAtoms::keyset, kNameSpaceID_XUL)) {
-        nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
-        if (xblService) {
-            xblService->DetachGlobalKeyHandler(aElement);
-        }
+        nsXBLService::DetachGlobalKeyHandler(aElement);
     }
 
     // 1. Remove any children from the document.
     for (nsIContent* child = aElement->GetLastChild();
          child;
          child = child->GetPreviousSibling()) {
 
         rv = RemoveSubtreeFromDocument(child);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -148,17 +148,17 @@
 #include "nsIDOMCSSRule.h"
 #include "nsICSSRuleList.h"
 #include "nsIDOMRect.h"
 #include "nsIDOMRGBColor.h"
 #include "nsIDOMNSRGBAColor.h"
 #include "nsDOMCSSAttrDeclaration.h"
 
 // XBL related includes.
-#include "nsIXBLService.h"
+#include "nsXBLService.h"
 #include "nsXBLBinding.h"
 #include "nsBindingManager.h"
 #include "nsIFrame.h"
 #include "nsIPresShell.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsStyleContext.h"
 #include "nsAutoPtr.h"
@@ -8025,17 +8025,17 @@ nsElementSH::PostCreate(nsIXPConnectWrap
   }
 
   nsCOMPtr<nsIURI> uri = bindingURL->GetURI();
   nsCOMPtr<nsIPrincipal> principal = bindingURL->mOriginPrincipal;
 
   // We have a binding that must be installed.
   bool dummy;
 
-  nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
+  nsXBLService* xblService = nsXBLService::GetInstance();
   NS_ENSURE_TRUE(xblService, NS_ERROR_NOT_AVAILABLE);
 
   nsRefPtr<nsXBLBinding> binding;
   xblService->LoadBindings(element, uri, principal, false,
                            getter_AddRefs(binding), &dummy);
   
   if (binding) {
     if (nsContentUtils::IsSafeToRunScript()) {
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -178,17 +178,17 @@
 #include "nsIArray.h"
 #include "nsIScriptRuntime.h"
 
 // XXX An unfortunate dependency exists here (two XUL files).
 #include "nsIDOMXULDocument.h"
 #include "nsIDOMXULCommandDispatcher.h"
 
 #include "nsBindingManager.h"
-#include "nsIXBLService.h"
+#include "nsXBLService.h"
 
 // used for popup blocking, needs to be converted to something
 // belonging to the back-end like nsIContentPolicy
 #include "nsIPopupWindowManager.h"
 
 #include "nsIDragService.h"
 #include "mozilla/dom/Element.h"
 #include "nsFrameLoader.h"
@@ -1713,20 +1713,17 @@ nsGlobalWindow::SetNewDocument(nsIDocume
     // First document load.
 
     // Get our private root. If it is equal to us, then we need to
     // attach our global key bindings that handles browser scrolling
     // and other browser commands.
     nsIDOMWindow* privateRoot = nsGlobalWindow::GetPrivateRoot();
 
     if (privateRoot == static_cast<nsIDOMWindow*>(this)) {
-      nsCOMPtr<nsIXBLService> xblService = do_GetService("@mozilla.org/xbl;1");
-      if (xblService) {
-        xblService->AttachGlobalKeyHandler(mChromeEventHandler);
-      }
+      nsXBLService::AttachGlobalKeyHandler(mChromeEventHandler);
     }
   }
 
   /* No mDocShell means we're already been partially closed down.  When that
      happens, setting status isn't a big requirement, so don't. (Doesn't happen
      under normal circumstances, but bug 49615 describes a case.) */
 
   nsContentUtils::AddScriptRunner(
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -97,17 +97,17 @@
 #include "nsAccessibilityService.h"
 #endif
 
 #include "nsInlineFrame.h"
 #include "nsBlockFrame.h"
 
 #include "nsIScrollableFrame.h"
 
-#include "nsIXBLService.h"
+#include "nsXBLService.h"
 
 #undef NOISY_FIRST_LETTER
 
 #include "nsMathMLParts.h"
 #include "nsIDOMSVGFilters.h"
 #include "DOMSVGTests.h"
 #include "nsSVGEffects.h"
 #include "nsSVGUtils.h"
@@ -189,19 +189,16 @@ NS_NewSVGFEUnstyledLeafFrame(nsIPresShel
 #include "nsIScrollable.h"
 #include "nsINodeInfo.h"
 #include "prenv.h"
 #include "nsWidgetsCID.h"
 #include "nsNodeInfoManager.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsIServiceManager.h"
 
-// Global object maintenance
-nsIXBLService * nsCSSFrameConstructor::gXBLService = nsnull;
-
 #ifdef DEBUG
 // Set the environment variable GECKO_FRAMECTOR_DEBUG_FLAGS to one or
 // more of the following flags (comma separated) for handy debug
 // output.
 static bool gNoisyContentUpdates = false;
 static bool gReallyNoisyContentUpdates = false;
 static bool gNoisyInlineConstruction = false;
 
@@ -1410,27 +1407,16 @@ nsCSSFrameConstructor::nsCSSFrameConstru
         printf("Note: GECKO_FRAMECTOR_DEBUG_FLAGS is a comma separated list of flag\n");
         printf("names (no whitespace)\n");
       }
     }
   }
 #endif
 }
 
-nsIXBLService * nsCSSFrameConstructor::GetXBLService()
-{
-  if (!gXBLService) {
-    nsresult rv = CallGetService("@mozilla.org/xbl;1", &gXBLService);
-    if (NS_FAILED(rv))
-      gXBLService = nsnull;
-  }
-  
-  return gXBLService;
-}
-
 void
 nsCSSFrameConstructor::NotifyDestroyingFrame(nsIFrame* aFrame)
 {
   NS_PRECONDITION(mUpdateCount != 0,
                   "Should be in an update while destroying frames");
 
   if (aFrame->GetStateBits() & NS_FRAME_GENERATED_CONTENT) {
     if (mQuoteList.DestroyNodesFor(aFrame))
@@ -2302,17 +2288,17 @@ nsCSSFrameConstructor::ConstructDocEleme
   const nsStyleDisplay* display = styleContext->GetStyleDisplay();
 
   // Ensure that our XBL bindings are installed.
   if (display->mBinding) {
     // Get the XBL loader.
     nsresult rv;
     bool resolveStyle;
     
-    nsIXBLService * xblService = GetXBLService();
+    nsXBLService* xblService = nsXBLService::GetInstance();
     if (!xblService)
       return NS_ERROR_FAILURE;
 
     nsRefPtr<nsXBLBinding> binding;
     rv = xblService->LoadBindings(aDocElement, display->mBinding->GetURI(),
                                   display->mBinding->mOriginPrincipal,
                                   false, getter_AddRefs(binding),
                                   &resolveStyle);
@@ -5039,17 +5025,17 @@ nsCSSFrameConstructor::AddFrameConstruct
   // can then be extended arbitrarily.
   const nsStyleDisplay* display = aStyleContext->GetStyleDisplay();
   nsRefPtr<nsStyleContext> styleContext(aStyleContext);
   PendingBinding* pendingBinding = nsnull;
   if ((aFlags & ITEM_ALLOW_XBL_BASE) && display->mBinding)
   {
     // Ensure that our XBL bindings are installed.
 
-    nsIXBLService * xblService = GetXBLService();
+    nsXBLService* xblService = nsXBLService::GetInstance();
     if (!xblService)
       return;
 
     bool resolveStyle;
 
     nsAutoPtr<PendingBinding> newPendingBinding(new PendingBinding());
 
     nsresult rv = xblService->LoadBindings(aContent, display->mBinding->GetURI(),
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -10,17 +10,16 @@
 
 #ifndef nsCSSFrameConstructor_h___
 #define nsCSSFrameConstructor_h___
 
 #include "mozilla/Attributes.h"
 
 #include "nsCOMPtr.h"
 #include "nsILayoutHistoryState.h"
-#include "nsIXBLService.h"
 #include "nsQuoteList.h"
 #include "nsCounterManager.h"
 #include "nsHashKeys.h"
 #include "nsThreadUtils.h"
 #include "nsPageContentFrame.h"
 #include "nsCSSPseudoElements.h"
 #include "RestyleTracker.h"
 #include "nsIAnonymousContentCreator.h"
@@ -58,20 +57,16 @@ public:
   nsCSSFrameConstructor(nsIDocument *aDocument, nsIPresShell* aPresShell);
   ~nsCSSFrameConstructor(void) {
     NS_ASSERTION(mUpdateCount == 0, "Dying in the middle of our own update?");
   }
 
   struct RestyleData;
   friend struct RestyleData;
 
-  // Maintain global objects - gXBLService
-  static nsIXBLService * GetXBLService();
-  static void ReleaseGlobals() { NS_IF_RELEASE(gXBLService); }
-
   // get the alternate text for a content node
   static void GetAlternateTextFor(nsIContent*    aContent,
                                   nsIAtom*       aTag,  // content object's tag
                                   nsXPIDLString& aAltText);
 
 private:
   nsCSSFrameConstructor(const nsCSSFrameConstructor& aCopy) MOZ_DELETE;
   nsCSSFrameConstructor& operator=(const nsCSSFrameConstructor& aCopy) MOZ_DELETE;
@@ -1827,13 +1822,11 @@ private:
   bool                mInStyleRefresh : 1;
   PRUint32            mHoverGeneration;
   nsChangeHint        mRebuildAllExtraHint;
 
   nsCOMPtr<nsILayoutHistoryState> mTempFrameTreeState;
 
   RestyleTracker mPendingRestyles;
   RestyleTracker mPendingAnimationRestyles;
-
-  static nsIXBLService * gXBLService;
 };
 
 #endif /* nsCSSFrameConstructor_h___ */
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -32,17 +32,16 @@
 #include "nsILayoutDebugger.h"
 #include "nsINameSpaceManager.h"
 #include "nsINodeInfo.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIPresShell.h"
 #include "nsIScriptNameSpaceManager.h"
 #include "nsISelection.h"
-#include "nsIXBLService.h"
 #include "nsCaret.h"
 #include "nsPlainTextSerializer.h"
 #include "nsXMLContentSerializer.h"
 #include "nsXHTMLContentSerializer.h"
 #include "nsRuleNode.h"
 #include "nsContentAreaDragDrop.h"
 #include "nsContentList.h"
 #include "nsBox.h"
@@ -398,17 +397,16 @@ nsresult NS_NewContentViewer(nsIContentV
 nsresult NS_NewContentIterator(nsIContentIterator** aResult);
 nsresult NS_NewPreContentIterator(nsIContentIterator** aResult);
 nsresult NS_NewGenRegularIterator(nsIContentIterator** aResult);
 nsresult NS_NewContentSubtreeIterator(nsIContentIterator** aResult);
 nsresult NS_NewGenSubtreeIterator(nsIContentIterator** aInstancePtrResult);
 nsresult NS_NewContentDocumentLoaderFactory(nsIDocumentLoaderFactory** aResult);
 nsresult NS_NewHTMLCopyTextEncoder(nsIDocumentEncoder** aResult);
 nsresult NS_NewTextEncoder(nsIDocumentEncoder** aResult);
-nsresult NS_NewXBLService(nsIXBLService** aResult);
 nsresult NS_NewContentPolicy(nsIContentPolicy** aResult);
 
 nsresult NS_NewEventListenerService(nsIEventListenerService** aResult);
 nsresult NS_NewGlobalMessageManager(nsIChromeFrameMessageManager** aResult);
 nsresult NS_NewParentProcessMessageManager(nsIFrameMessageManager** aResult);
 nsresult NS_NewChildProcessMessageManager(nsISyncMessageSender** aResult);
 
 nsresult NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult);
@@ -469,17 +467,16 @@ MAKE_CTOR(CreateSubtreeIterator,        
 // CreateHTMLOptionElement, see below
 // CreateHTMLAudioElement, see below
 MAKE_CTOR(CreateTextEncoder,              nsIDocumentEncoder,          NS_NewTextEncoder)
 MAKE_CTOR(CreateHTMLCopyTextEncoder,      nsIDocumentEncoder,          NS_NewHTMLCopyTextEncoder)
 MAKE_CTOR(CreateXMLContentSerializer,     nsIContentSerializer,        NS_NewXMLContentSerializer)
 MAKE_CTOR(CreateHTMLContentSerializer,    nsIContentSerializer,        NS_NewHTMLContentSerializer)
 MAKE_CTOR(CreateXHTMLContentSerializer,   nsIContentSerializer,        NS_NewXHTMLContentSerializer)
 MAKE_CTOR(CreatePlainTextSerializer,      nsIContentSerializer,        NS_NewPlainTextSerializer)
-MAKE_CTOR(CreateXBLService,               nsIXBLService,               NS_NewXBLService)
 MAKE_CTOR(CreateContentPolicy,            nsIContentPolicy,            NS_NewContentPolicy)
 #ifdef MOZ_XUL
 MAKE_CTOR(CreateXULSortService,           nsIXULSortService,           NS_NewXULSortService)
 // NS_NewXULContentBuilder
 // NS_NewXULTreeBuilder
 MAKE_CTOR(CreateXULDocument,              nsIXULDocument,              NS_NewXULDocument)
 // NS_NewXULControllers
 #endif
@@ -667,17 +664,16 @@ NS_DEFINE_NAMED_CID(NS_CANVASRENDERINGCO
 NS_DEFINE_NAMED_CID(NS_TEXT_ENCODER_CID);
 NS_DEFINE_NAMED_CID(NS_HTMLCOPY_TEXT_ENCODER_CID);
 NS_DEFINE_NAMED_CID(NS_XMLCONTENTSERIALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_XHTMLCONTENTSERIALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_HTMLCONTENTSERIALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_PLAINTEXTSERIALIZER_CID);
 NS_DEFINE_NAMED_CID(NS_PARSERUTILS_CID);
 NS_DEFINE_NAMED_CID(NS_SCRIPTABLEUNESCAPEHTML_CID);
-NS_DEFINE_NAMED_CID(NS_XBLSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_CONTENTPOLICY_CID);
 NS_DEFINE_NAMED_CID(NS_DATADOCUMENTCONTENTPOLICY_CID);
 NS_DEFINE_NAMED_CID(NS_NODATAPROTOCOLCONTENTPOLICY_CID);
 NS_DEFINE_NAMED_CID(NS_XULCONTROLLERS_CID);
 #ifdef MOZ_XUL
 NS_DEFINE_NAMED_CID(NS_XULSORTSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_XULTEMPLATEBUILDER_CID);
 NS_DEFINE_NAMED_CID(NS_XULTREEBUILDER_CID);
@@ -937,17 +933,16 @@ static const mozilla::Module::CIDEntry k
   { &kNS_TEXT_ENCODER_CID, false, NULL, CreateTextEncoder },
   { &kNS_HTMLCOPY_TEXT_ENCODER_CID, false, NULL, CreateHTMLCopyTextEncoder },
   { &kNS_XMLCONTENTSERIALIZER_CID, false, NULL, CreateXMLContentSerializer },
   { &kNS_HTMLCONTENTSERIALIZER_CID, false, NULL, CreateHTMLContentSerializer },
   { &kNS_XHTMLCONTENTSERIALIZER_CID, false, NULL, CreateXHTMLContentSerializer },
   { &kNS_PLAINTEXTSERIALIZER_CID, false, NULL, CreatePlainTextSerializer },
   { &kNS_PARSERUTILS_CID, false, NULL, nsParserUtilsConstructor },
   { &kNS_SCRIPTABLEUNESCAPEHTML_CID, false, NULL, nsParserUtilsConstructor },
-  { &kNS_XBLSERVICE_CID, false, NULL, CreateXBLService },
   { &kNS_CONTENTPOLICY_CID, false, NULL, CreateContentPolicy },
   { &kNS_DATADOCUMENTCONTENTPOLICY_CID, false, NULL, nsDataDocumentContentPolicyConstructor },
   { &kNS_NODATAPROTOCOLCONTENTPOLICY_CID, false, NULL, nsNoDataProtocolContentPolicyConstructor },
   { &kNS_XULCONTROLLERS_CID, false, NULL, NS_NewXULControllers },
 #ifdef MOZ_XUL
   { &kNS_XULSORTSERVICE_CID, false, NULL, CreateXULSortService },
   { &kNS_XULTEMPLATEBUILDER_CID, false, NULL, NS_NewXULContentBuilder },
   { &kNS_XULTREEBUILDER_CID, false, NULL, NS_NewXULTreeBuilder },
@@ -1079,17 +1074,16 @@ static const mozilla::Module::ContractID
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "application/xml", &kNS_XMLCONTENTSERIALIZER_CID },
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "application/xhtml+xml", &kNS_XHTMLCONTENTSERIALIZER_CID },
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "image/svg+xml", &kNS_XMLCONTENTSERIALIZER_CID },
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "text/html", &kNS_HTMLCONTENTSERIALIZER_CID },
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "application/vnd.mozilla.xul+xml", &kNS_XMLCONTENTSERIALIZER_CID },
   { NS_CONTENTSERIALIZER_CONTRACTID_PREFIX "text/plain", &kNS_PLAINTEXTSERIALIZER_CID },
   { NS_PARSERUTILS_CONTRACTID, &kNS_PARSERUTILS_CID },
   { NS_SCRIPTABLEUNESCAPEHTML_CONTRACTID, &kNS_SCRIPTABLEUNESCAPEHTML_CID },
-  { "@mozilla.org/xbl;1", &kNS_XBLSERVICE_CID },
   { NS_CONTENTPOLICY_CONTRACTID, &kNS_CONTENTPOLICY_CID },
   { NS_DATADOCUMENTCONTENTPOLICY_CONTRACTID, &kNS_DATADOCUMENTCONTENTPOLICY_CID },
   { NS_NODATAPROTOCOLCONTENTPOLICY_CONTRACTID, &kNS_NODATAPROTOCOLCONTENTPOLICY_CID },
   { "@mozilla.org/xul/xul-controllers;1", &kNS_XULCONTROLLERS_CID },
 #ifdef MOZ_XUL
   { "@mozilla.org/xul/xul-sort-service;1", &kNS_XULSORTSERVICE_CID },
   { "@mozilla.org/xul/xul-template-builder;1", &kNS_XULTEMPLATEBUILDER_CID },
   { "@mozilla.org/xul/xul-tree-builder;1", &kNS_XULTREEBUILDER_CID },
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -7,17 +7,16 @@
 
 #include "nsAttrValue.h"
 #include "nsAutoCopyListener.h"
 #include "nsColorNames.h"
 #include "nsComputedDOMStyle.h"
 #include "nsContentDLF.h"
 #include "nsContentUtils.h"
 #include "nsCSSAnonBoxes.h"
-#include "nsCSSFrameConstructor.h"
 #include "nsCSSKeywords.h"
 #include "nsCSSParser.h"
 #include "nsCSSProps.h"
 #include "nsCSSPseudoClasses.h"
 #include "nsCSSPseudoElements.h"
 #include "nsCSSRendering.h"
 #include "nsCSSScanner.h"
 #include "nsDOMAttribute.h"
@@ -33,16 +32,17 @@
 #include "nsRegion.h"
 #include "nsRepeatService.h"
 #include "nsFloatManager.h"
 #include "nsSprocketLayout.h"
 #include "nsStackLayout.h"
 #include "nsStyleSet.h"
 #include "nsTextControlFrame.h"
 #include "nsXBLWindowKeyHandler.h"
+#include "nsXBLService.h"
 #include "txMozillaXSLTProcessor.h"
 #include "nsDOMStorage.h"
 #include "nsTreeSanitizer.h"
 #include "nsCellMap.h"
 #include "nsTextFrameTextRunCache.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsTextFragment.h"
 #include "nsCSSRuleProcessor.h"
@@ -56,17 +56,16 @@
 #include "nsSVGUtils.h"
 #include "nsMathMLAtoms.h"
 #include "nsMathMLOperators.h"
 #include "Navigator.h"
 
 #ifdef MOZ_XUL
 #include "nsXULPopupManager.h"
 #include "nsXULContentUtils.h"
-#include "nsXULElement.h"
 #include "nsXULPrototypeCache.h"
 #include "nsXULTooltipListener.h"
 
 #include "inDOMView.h"
 #endif
 
 #include "nsHTMLEditor.h"
 #include "nsTextServicesDocument.h"
@@ -124,16 +123,17 @@ nsLayoutStatics::Initialize()
   rv = nsRegion::InitStatic();
   if (NS_FAILED(rv)) {
     NS_ERROR("Could not initialize nsRegion");
     return rv;
   }
 
   nsGlobalWindow::Init();
   Navigator::Init();
+  nsXBLService::Init();
 
   rv = nsContentUtils::Init();
   if (NS_FAILED(rv)) {
     NS_ERROR("Could not initialize nsContentUtils");
     return rv;
   }
 
   rv = nsAttrValue::Init();
@@ -274,24 +274,22 @@ nsLayoutStatics::Shutdown()
   nsCSSProps::ReleaseTable();
   nsCSSKeywords::ReleaseTable();
   nsRepeatService::Shutdown();
   nsStackLayout::Shutdown();
   nsBox::Shutdown();
 
 #ifdef MOZ_XUL
   nsXULContentUtils::Finish();
-  nsXULElement::ReleaseGlobals();
   nsXULPrototypeCache::ReleaseGlobals();
   nsSprocketLayout::Shutdown();
 #endif
 
   nsMathMLOperators::ReleaseTable();
 
-  nsCSSFrameConstructor::ReleaseGlobals();
   nsFloatManager::Shutdown();
   nsImageFrame::ReleaseGlobals();
 
   nsCSSScanner::ReleaseGlobals();
 
   nsTextFragment::Shutdown();
 
   nsAttrValue::Shutdown();
@@ -300,16 +298,17 @@ nsLayoutStatics::Shutdown()
   nsLayoutStylesheetCache::Shutdown();
   NS_NameSpaceManagerShutdown();
 
   nsJSRuntime::Shutdown();
   nsGlobalWindow::ShutDown();
   nsDOMClassInfo::ShutDown();
   nsListControlFrame::Shutdown();
   nsXBLWindowKeyHandler::ShutDown();
+  nsXBLService::Shutdown();
   nsAutoCopyListener::Shutdown();
 
 #ifdef MOZ_SYDNEYAUDIO
   nsAudioStream::ShutdownLibrary();
 #endif
 
   nsCORSListenerProxy::Shutdown();
   
--- a/layout/xul/base/src/nsSplitterFrame.cpp
+++ b/layout/xul/base/src/nsSplitterFrame.cpp
@@ -23,17 +23,16 @@
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMEventListener.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIPresShell.h"
 #include "nsFrameList.h"
 #include "nsHTMLParts.h"
 #include "nsStyleContext.h"
 #include "nsBoxLayoutState.h"
-#include "nsIXBLService.h"
 #include "nsIServiceManager.h"
 #include "nsContainerFrame.h"
 #include "nsGUIEvent.h"
 #include "nsAutoPtr.h"
 #include "nsContentCID.h"
 #include "nsStyleSet.h"
 #include "nsLayoutUtils.h"
 #include "nsDisplayList.h"
--- a/widget/cocoa/nsMenuX.mm
+++ b/widget/cocoa/nsMenuX.mm
@@ -28,17 +28,17 @@
 
 #include "nsIDocument.h"
 #include "nsIContent.h"
 #include "nsIDOMDocument.h"
 #include "nsIDocumentObserver.h"
 #include "nsIComponentManager.h"
 #include "nsIRollupListener.h"
 #include "nsIDOMElement.h"
-#include "nsIXBLService.h"
+#include "nsBindingManager.h"
 #include "nsIServiceManager.h"
 
 #include "jsapi.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptContext.h"
 #include "nsIXPConnect.h"
 
 // externs defined in nsChildView.mm
@@ -667,42 +667,35 @@ bool nsMenuX::OnClose()
 // of a very few children so we won't be iterating over a bazillion menu items to find
 // it (so the strcmp won't kill us).
 void nsMenuX::GetMenuPopupContent(nsIContent** aResult)
 {
   if (!aResult)
     return;
   *aResult = nsnull;
   
-  nsresult rv;
-  nsCOMPtr<nsIXBLService> xblService = do_GetService("@mozilla.org/xbl;1", &rv);
-  if (!xblService)
-    return;
-
   // Check to see if we are a "menupopup" node (if we are a native menu).
   {
     PRInt32 dummy;
-    nsCOMPtr<nsIAtom> tag;
-    xblService->ResolveTag(mContent, &dummy, getter_AddRefs(tag));
+    nsCOMPtr<nsIAtom> tag = mContent->OwnerDoc()->BindingManager()->ResolveTag(mContent, &dummy);
     if (tag == nsGkAtoms::menupopup) {
       *aResult = mContent;
       NS_ADDREF(*aResult);
       return;
     }
   }
 
   // Otherwise check our child nodes.
   
   PRUint32 count = mContent->GetChildCount();
 
   for (PRUint32 i = 0; i < count; i++) {
     PRInt32 dummy;
     nsIContent *child = mContent->GetChildAt(i);
-    nsCOMPtr<nsIAtom> tag;
-    xblService->ResolveTag(child, &dummy, getter_AddRefs(tag));
+    nsCOMPtr<nsIAtom> tag = child->OwnerDoc()->BindingManager()->ResolveTag(child, &dummy);
     if (tag == nsGkAtoms::menupopup) {
       *aResult = child;
       NS_ADDREF(*aResult);
       return;
     }
   }
 }