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

* * *
* * *
* * *
* * *
* * *
* * *
* * *

diff --git a/netwerk/base/src/nsIOService.cpp b/netwerk/base/src/nsIOService.cpp
--- a/netwerk/base/src/nsIOService.cpp
+++ b/netwerk/base/src/nsIOService.cpp
@@ -170,7 +170,7 @@ nsIOService::nsIOService()
     if (!gBufferCache)
     {
         nsresult rv = NS_OK;
-        nsCOMPtr<nsIRecyclingAllocator> recyclingAllocator =
+        nsIRecyclingAllocator* recyclingAllocator =
             do_CreateInstance(NS_RECYCLINGALLOCATOR_CONTRACTID, &rv);
         if (NS_FAILED(rv))
             return;
@@ -179,9 +179,8 @@ nsIOService::nsIOService()
         if (NS_FAILED(rv))
             return;
 
-        nsCOMPtr<nsIMemory> eyeMemory = do_QueryInterface(recyclingAllocator);
-        gBufferCache = eyeMemory.get();
-        NS_IF_ADDREF(gBufferCache);
+        gBufferCache = recyclingAllocator;
+        NS_RootUntilShutdown(gBufferCache);
     }
 }
 
@@ -209,7 +208,7 @@ nsIOService::Init()
     }
 
     // XXX hack until xpidl supports error info directly (bug 13423)
-    nsCOMPtr<nsIErrorService> errorService = do_GetService(NS_ERRORSERVICE_CONTRACTID);
+    nsIErrorService* errorService = do_GetService(NS_ERRORSERVICE_CONTRACTID);
     if (errorService) {
         errorService->RegisterErrorStringBundle(NS_ERROR_MODULE_NETWORK, NECKO_MSGS_URL);
     }
@@ -221,8 +220,8 @@ nsIOService::Init()
         mRestrictedPortList.AppendElement(reinterpret_cast<void *>(gBadPortList[i]));
 
     // Further modifications to the port list come from prefs
-    nsCOMPtr<nsIPrefBranch2> prefBranch;
-    GetPrefBranch(getter_AddRefs(prefBranch));
+    nsIPrefBranch2* prefBranch = nsnull;
+    GetPrefBranch(&prefBranch);
     if (prefBranch) {
         prefBranch->AddObserver(PORT_PREF_PREFIX, this, PR_TRUE);
         prefBranch->AddObserver(AUTODIAL_PREF, this, PR_TRUE);
@@ -230,7 +229,7 @@ nsIOService::Init()
     }
     
     // Register for profile change notifications
-    nsCOMPtr<nsIObserverService> observerService =
+    nsIObserverService* observerService =
         do_GetService("@mozilla.org/observer-service;1");
     if (observerService) {
         observerService->AddObserver(this, kProfileChangeNetTeardownTopic, PR_TRUE);
@@ -265,7 +264,6 @@ nsIOService::GetInstance() {
         gIOService = new nsIOService();
         if (!gIOService)
             return nsnull;
-        NS_ADDREF(gIOService);
 
         nsresult rv = gIOService->Init();
         if (NS_FAILED(rv)) {
@@ -274,7 +272,6 @@ nsIOService::GetInstance() {
         }
         return gIOService;
     }
-    NS_ADDREF(gIOService);
     return gIOService;
 }
 
@@ -291,7 +288,7 @@ nsIOService::OnChannelRedirect(nsIChanne
 nsIOService::OnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan,
                                PRUint32 flags)
 {
-    nsCOMPtr<nsIChannelEventSink> sink =
+    nsIChannelEventSink* sink =
         do_GetService(NS_GLOBAL_CHANNELEVENTSINK_CONTRACTID);
     if (sink) {
         nsresult rv = sink->OnChannelRedirect(oldChan, newChan, flags);
@@ -322,7 +319,7 @@ nsIOService::CacheProtocolHandler(const 
             nsresult rv;
             NS_ASSERTION(!mWeakHandler[i], "Protocol handler already cached");
             // Make sure the handler supports weak references.
-            nsCOMPtr<nsISupportsWeakReference> factoryPtr = do_QueryInterface(handler, &rv);
+            nsISupportsWeakReference* factoryPtr = do_QueryInterface(handler, &rv);
             if (!factoryPtr)
             {
                 // Don't cache handlers that don't support weak reference as
@@ -376,8 +373,8 @@ nsIOService::GetProtocolHandler(const ch
 
     PRBool externalProtocol = PR_FALSE;
     PRBool listedProtocol   = PR_TRUE;
-    nsCOMPtr<nsIPrefBranch2> prefBranch;
-    GetPrefBranch(getter_AddRefs(prefBranch));
+    nsIPrefBranch2* prefBranch = nsnull;
+    GetPrefBranch(&prefBranch);
     if (prefBranch) {
         nsCAutoString externalProtocolPref("network.protocol-handler.external.");
         externalProtocolPref += scheme;
@@ -448,8 +445,8 @@ NS_IMETHODIMP
 NS_IMETHODIMP 
 nsIOService::GetProtocolFlags(const char* scheme, PRUint32 *flags)
 {
-    nsCOMPtr<nsIProtocolHandler> handler;
-    nsresult rv = GetProtocolHandler(scheme, getter_AddRefs(handler));
+    nsIProtocolHandler* handler = nsnull;
+    nsresult rv = GetProtocolHandler(scheme, &handler);
     if (NS_FAILED(rv)) return rv;
 
     rv = handler->GetProtocolFlags(flags);
@@ -493,8 +490,8 @@ nsIOService::NewURI(const nsACString &aS
     }
 
     // now get the handler for this scheme
-    nsCOMPtr<nsIProtocolHandler> handler;
-    rv = GetProtocolHandler(scheme.get(), getter_AddRefs(handler));
+    nsIProtocolHandler* handler = nsnull;
+    rv = GetProtocolHandler(scheme.get(), &handler);
     if (NS_FAILED(rv)) return rv;
 
     return handler->NewURI(aSpec, aCharset, aBaseURI, result);
@@ -507,12 +504,12 @@ nsIOService::NewFileURI(nsIFile *file, n
     nsresult rv;
     NS_ENSURE_ARG_POINTER(file);
 
-    nsCOMPtr<nsIProtocolHandler> handler;
+    nsIProtocolHandler* handler = nsnull;
 
-    rv = GetProtocolHandler("file", getter_AddRefs(handler));
+    rv = GetProtocolHandler("file", &handler);
     if (NS_FAILED(rv)) return rv;
 
-    nsCOMPtr<nsIFileProtocolHandler> fileHandler( do_QueryInterface(handler, &rv) );
+    nsIFileProtocolHandler* fileHandler( do_QueryInterface(handler, &rv) );
     if (NS_FAILED(rv)) return rv;
     
     return fileHandler->NewFileURI(file, result);
@@ -530,8 +527,8 @@ nsIOService::NewChannelFromURI(nsIURI *a
     if (NS_FAILED(rv))
         return rv;
 
-    nsCOMPtr<nsIProtocolHandler> handler;
-    rv = GetProtocolHandler(scheme.get(), getter_AddRefs(handler));
+    nsIProtocolHandler* handler = nsnull;
+    rv = GetProtocolHandler(scheme.get(), &handler);
     if (NS_FAILED(rv))
         return rv;
 
@@ -543,14 +540,14 @@ nsIOService::NewChannelFromURI(nsIURI *a
     // Talk to the PPS if the protocol handler allows proxying.  Otherwise,
     // skip this step.  This allows us to lazily load the PPS at startup.
     if (protoFlags & nsIProtocolHandler::ALLOWS_PROXY) {
-        nsCOMPtr<nsIProxyInfo> pi;
+        nsIProxyInfo* pi = nsnull;
         if (!mProxyService) {
             mProxyService = do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID);
             if (!mProxyService)
                 NS_WARNING("failed to get protocol proxy service");
         }
         if (mProxyService) {
-            rv = mProxyService->Resolve(aURI, 0, getter_AddRefs(pi));
+            rv = mProxyService->Resolve(aURI, 0, &pi);
             if (NS_FAILED(rv))
                 pi = nsnull;
         }
@@ -558,11 +555,11 @@ nsIOService::NewChannelFromURI(nsIURI *a
             nsCAutoString type;
             if (NS_SUCCEEDED(pi->GetType(type)) && type.EqualsLiteral("http")) {
                 // we are going to proxy this channel using an http proxy
-                rv = GetProtocolHandler("http", getter_AddRefs(handler));
+                rv = GetProtocolHandler("http", &handler);
                 if (NS_FAILED(rv))
                     return rv;
             }
-            nsCOMPtr<nsIProxiedProtocolHandler> pph = do_QueryInterface(handler);
+            nsIProxiedProtocolHandler* pph = do_QueryInterface(handler);
             if (pph)
                 return pph->NewProxiedChannel(aURI, pi, result);
         }
@@ -575,8 +572,8 @@ nsIOService::NewChannel(const nsACString
 nsIOService::NewChannel(const nsACString &aSpec, const char *aCharset, nsIURI *aBaseURI, nsIChannel **result)
 {
     nsresult rv;
-    nsCOMPtr<nsIURI> uri;
-    rv = NewURI(aSpec, aCharset, aBaseURI, getter_AddRefs(uri));
+    nsIURI* uri = nsnull;
+    rv = NewURI(aSpec, aCharset, aBaseURI, &uri);
     if (NS_FAILED(rv)) return rv;
 
     return NewChannelFromURI(uri, result);
@@ -592,7 +589,7 @@ NS_IMETHODIMP
 NS_IMETHODIMP
 nsIOService::SetOffline(PRBool offline)
 {
-    nsCOMPtr<nsIObserverService> observerService =
+    nsIObserverService* observerService =
         do_GetService("@mozilla.org/observer-service;1");
     
     nsresult rv;
@@ -672,8 +669,8 @@ nsIOService::AllowPort(PRInt32 inPort, c
             if (!scheme)
                 return NS_OK;
             
-            nsCOMPtr<nsIProtocolHandler> handler;
-            nsresult rv = GetProtocolHandler(scheme, getter_AddRefs(handler));
+            nsIProtocolHandler* handler = nsnull;
+            nsresult rv = GetProtocolHandler(scheme, &handler);
             if (NS_FAILED(rv)) return rv;
 
             // let the protocol handler decide
@@ -765,7 +762,7 @@ nsIOService::Observe(nsISupports *subjec
                      const PRUnichar *data)
 {
     if (!strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
-        nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(subject);
+        nsIPrefBranch* prefBranch = do_QueryInterface(subject);
         if (prefBranch)
             PrefsChanged(prefBranch, NS_ConvertUTF16toUTF8(data).get());
     }
@@ -846,10 +843,10 @@ nsIOService::URIChainHasFlags(nsIURI   *
 
     // Dig deeper into the chain.  Note that this is not a do/while loop to
     // avoid the extra addref/release on |uri| in the common (non-nested) case.
-    nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(uri);
+    nsINestedURI* nestedURI = do_QueryInterface(uri);
     while (nestedURI) {
-        nsCOMPtr<nsIURI> innerURI;
-        rv = nestedURI->GetInnerURI(getter_AddRefs(innerURI));
+        nsIURI* innerURI = nsnull;
+        rv = nestedURI->GetInnerURI(&innerURI);
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = ProtocolHasFlags(innerURI, flags, result);
diff --git a/netwerk/base/src/nsLoadGroup.cpp b/netwerk/base/src/nsLoadGroup.cpp
--- a/netwerk/base/src/nsLoadGroup.cpp
+++ b/netwerk/base/src/nsLoadGroup.cpp
@@ -178,8 +178,8 @@ nsresult nsLoadGroup::Init()
 {
     static PLDHashTableOps hash_table_ops =
     {
-        PL_DHashAllocTable,
-        PL_DHashFreeTable,
+        GCAllocTable,
+        GCFreeTable,
         PL_DHashVoidPtrKeyStub,
         RequestHashMatchEntry,
         PL_DHashMoveEntryStub,
diff --git a/netwerk/base/src/nsPACMan.cpp b/netwerk/base/src/nsPACMan.cpp
--- a/netwerk/base/src/nsPACMan.cpp
+++ b/netwerk/base/src/nsPACMan.cpp
@@ -74,7 +74,7 @@ HttpRequestSucceeded(nsIStreamLoader *lo
 
 // These objects are stored in nsPACMan::mPendingQ
 
-class PendingPACQuery : public PRCList, public nsIDNSListener
+class PendingPACQuery : public nsIDNSListener, public PRCList
 {
 public:
   NS_DECL_ISUPPORTS
diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp
--- a/netwerk/base/src/nsSocketTransport2.cpp
+++ b/netwerk/base/src/nsSocketTransport2.cpp
@@ -221,7 +221,6 @@ nsSocketInputStream::nsSocketInputStream
 
 nsSocketInputStream::~nsSocketInputStream()
 {
-    Close();
 }
 
 // called on the socket transport thread...
@@ -236,7 +235,7 @@ nsSocketInputStream::OnSocketReady(nsres
 
     NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
 
-    nsCOMPtr<nsIInputStreamCallback> callback;
+    nsIInputStreamCallback* callback = nsnull;
     {
         nsAutoLock lock(mTransport->mLock);
 
@@ -418,7 +417,7 @@ nsSocketInputStream::AsyncWait(nsIInputS
     // This variable will be non-null when we want to call the callback
     // directly from this function, but outside the lock.
     // (different from callback when target is not null)
-    nsCOMPtr<nsIInputStreamCallback> directCallback;
+    nsIInputStreamCallback* directCallback = nsnull;
     {
         nsAutoLock lock(mTransport->mLock);
 
@@ -429,8 +428,8 @@ nsSocketInputStream::AsyncWait(nsIInputS
             // failure to create an event proxy (most likely out of memory)
             // shouldn't alter the state of the transport.
             //
-            nsCOMPtr<nsIInputStreamCallback> temp;
-            nsresult rv = NS_NewInputStreamReadyEvent(getter_AddRefs(temp),
+            nsIInputStreamCallback* temp = nsnull;
+            nsresult rv = NS_NewInputStreamReadyEvent(&temp,
                                                       callback, target);
             if (NS_FAILED(rv)) return rv;
             mCallback = temp;
@@ -439,7 +438,7 @@ nsSocketInputStream::AsyncWait(nsIInputS
             mCallback = callback;
 
         if (NS_FAILED(mCondition))
-            directCallback.swap(mCallback);
+            swap(directCallback, mCallback);
         else
             mCallbackFlags = flags;
     }
@@ -466,7 +465,6 @@ nsSocketOutputStream::nsSocketOutputStre
 
 nsSocketOutputStream::~nsSocketOutputStream()
 {
-  Close();
 }
 
 // called on the socket transport thread...
@@ -481,7 +479,7 @@ nsSocketOutputStream::OnSocketReady(nsre
 
     NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
 
-    nsCOMPtr<nsIOutputStreamCallback> callback;
+    nsIOutputStreamCallback* callback = nsnull;
     {
         nsAutoLock lock(mTransport->mLock);
 
@@ -653,8 +651,8 @@ nsSocketOutputStream::AsyncWait(nsIOutpu
             // failure to create an event proxy (most likely out of memory)
             // shouldn't alter the state of the transport.
             //
-            nsCOMPtr<nsIOutputStreamCallback> temp;
-            nsresult rv = NS_NewOutputStreamReadyEvent(getter_AddRefs(temp),
+            nsIOutputStreamCallback* temp = nsnull;
+            nsresult rv = NS_NewOutputStreamReadyEvent(&temp,
                                                        callback, target);
             if (NS_FAILED(rv)) return rv;
             mCallback = temp;
@@ -693,7 +691,6 @@ nsSocketTransport::nsSocketTransport()
 {
     LOG(("creating nsSocketTransport @%x\n", this));
 
-    NS_ADDREF(gSocketTransportService);
 
     mTimeouts[TIMEOUT_CONNECT]    = PR_UINT16_MAX; // no timeout
     mTimeouts[TIMEOUT_READ_WRITE] = PR_UINT16_MAX; // no timeout
@@ -726,7 +723,7 @@ nsSocketTransport::Init(const char **typ
     if (!mLock)
         return NS_ERROR_OUT_OF_MEMORY;
 
-    nsCOMPtr<nsProxyInfo> proxyInfo;
+    nsProxyInfo* proxyInfo = nsnull;
     if (givenProxyInfo) {
         proxyInfo = do_QueryInterface(givenProxyInfo);
         NS_ENSURE_ARG(proxyInfo);
@@ -760,7 +757,7 @@ nsSocketTransport::Init(const char **typ
     // if we have socket types, then the socket provider service had
     // better exist!
     nsresult rv;
-    nsCOMPtr<nsISocketProviderService> spserv =
+    nsISocketProviderService* spserv =
         do_GetService(kSocketProviderServiceCID, &rv);
     if (NS_FAILED(rv)) return rv;
 
@@ -780,8 +777,8 @@ nsSocketTransport::Init(const char **typ
             mTypeCount = i;
             return NS_ERROR_OUT_OF_MEMORY;
         }
-        nsCOMPtr<nsISocketProvider> provider;
-        rv = spserv->GetSocketProvider(mTypes[i], getter_AddRefs(provider));
+        nsISocketProvider* provider = nsnull;
+        rv = spserv->GetSocketProvider(mTypes[i], &provider);
         if (NS_FAILED(rv)) {
             NS_WARNING("no registered socket provider");
             return rv;
@@ -852,7 +849,7 @@ nsSocketTransport::PostEvent(PRUint32 ty
     LOG(("nsSocketTransport::PostEvent [this=%p type=%u status=%x param=%p]\n",
         this, type, status, param));
 
-    nsCOMPtr<nsIRunnable> event = new nsSocketEvent(this, type, status, param);
+    nsIRunnable* event = new nsSocketEvent(this, type, status, param);
     if (!event)
         return NS_ERROR_OUT_OF_MEMORY;
 
@@ -864,7 +861,7 @@ nsSocketTransport::SendStatus(nsresult s
 {
     LOG(("nsSocketTransport::SendStatus [this=%x status=%x]\n", this, status));
 
-    nsCOMPtr<nsITransportEventSink> sink;
+    nsITransportEventSink* sink = nsnull;
     PRUint64 progress;
     {
         nsAutoLock lock(mLock);
@@ -913,7 +910,7 @@ nsSocketTransport::ResolveHost()
         }
     }
 
-    nsCOMPtr<nsIDNSService> dns = do_GetService(kDNSServiceCID, &rv);
+    nsIDNSService* dns = do_GetService(kDNSServiceCID, &rv);
     if (NS_FAILED(rv)) return rv;
 
     mResolving = PR_TRUE;
@@ -947,7 +944,7 @@ nsSocketTransport::BuildSocket(PRFileDes
     else {
         fd = nsnull;
 
-        nsCOMPtr<nsISocketProviderService> spserv =
+        nsISocketProviderService* spserv =
             do_GetService(kSocketProviderServiceCID, &rv);
         if (NS_FAILED(rv)) return rv;
 
@@ -959,25 +956,25 @@ nsSocketTransport::BuildSocket(PRFileDes
 
         PRUint32 i;
         for (i=0; i<mTypeCount; ++i) {
-            nsCOMPtr<nsISocketProvider> provider;
+            nsISocketProvider* provider = nsnull;
 
             LOG(("  pushing io layer [%u:%s]\n", i, mTypes[i]));
 
-            rv = spserv->GetSocketProvider(mTypes[i], getter_AddRefs(provider));
+            rv = spserv->GetSocketProvider(mTypes[i], &provider);
             if (NS_FAILED(rv))
                 break;
 
             if (mProxyTransparentResolvesHost)
                 proxyFlags |= nsISocketProvider::PROXY_RESOLVES_HOST;
 
-            nsCOMPtr<nsISupports> secinfo;
+            nsISupports* secinfo = nsnull;
             if (i == 0) {
                 // if this is the first type, we'll want the 
                 // service to allocate a new socket
                 rv = provider->NewSocket(mNetAddr.raw.family,
                                          host, port, proxyHost, proxyPort,
                                          proxyFlags, &fd,
-                                         getter_AddRefs(secinfo));
+                                         &secinfo);
 
                 if (NS_SUCCEEDED(rv) && !fd) {
                     NS_NOTREACHED("NewSocket succeeded but failed to create a PRFileDesc");
@@ -991,7 +988,7 @@ nsSocketTransport::BuildSocket(PRFileDes
                 rv = provider->AddToSocket(mNetAddr.raw.family,
                                            host, port, proxyHost, proxyPort,
                                            proxyFlags, fd,
-                                           getter_AddRefs(secinfo));
+                                           &secinfo);
             }
             proxyFlags = 0;
             if (NS_FAILED(rv))
@@ -1001,7 +998,7 @@ nsSocketTransport::BuildSocket(PRFileDes
             PRBool isSSL = (strcmp(mTypes[i], "ssl") == 0);
             if (isSSL || (strcmp(mTypes[i], "starttls") == 0)) {
                 // remember security info and give notification callbacks to PSM...
-                nsCOMPtr<nsIInterfaceRequestor> callbacks;
+                nsIInterfaceRequestor* callbacks = nsnull;
                 {
                     nsAutoLock lock(mLock);
                     mSecInfo = secinfo;
@@ -1009,7 +1006,7 @@ nsSocketTransport::BuildSocket(PRFileDes
                     LOG(("  [secinfo=%x callbacks=%x]\n", mSecInfo.get(), mCallbacks.get()));
                 }
                 // don't call into PSM while holding mLock!!
-                nsCOMPtr<nsISSLSocketControl> secCtrl(do_QueryInterface(secinfo));
+                nsISSLSocketControl* secCtrl(do_QueryInterface(secinfo));
                 if (secCtrl)
                     secCtrl->SetNotificationCallbacks(callbacks);
                 // remember if socket type is SSL so we can ProxyStartSSL if need be.
@@ -1055,7 +1052,7 @@ nsSocketTransport::InitiateSocket()
     // 194402 for more info.
     //
     if (!gSocketTransportService->CanAttachSocket()) {
-        nsCOMPtr<nsIRunnable> event =
+        nsIRunnable* event =
                 new nsSocketEvent(this, MSG_RETRY_INIT_SOCKET);
         if (!event)
             return NS_ERROR_OUT_OF_MEMORY;
@@ -1158,7 +1155,7 @@ nsSocketTransport::InitiateSocket()
                 // been pushed, and we were proxying (transparently; ie. nothing
                 // has to happen in the protocol layer above us), it's time for
                 // the ssl to start doing it's thing.
-                nsCOMPtr<nsISSLSocketControl> secCtrl =
+                nsISSLSocketControl* secCtrl =
                     do_QueryInterface(mSecInfo);
                 if (secCtrl) {
                     LOG(("  calling ProxyStartSSL()\n"));
@@ -1549,7 +1546,7 @@ nsSocketTransport::OnSocketDetached(PRFi
     // break any potential reference cycle between the security info object
     // and ourselves by resetting its notification callbacks object.  see
     // bug 285991 for details.
-    nsCOMPtr<nsISSLSocketControl> secCtrl = do_QueryInterface(mSecInfo);
+    nsISSLSocketControl* secCtrl = do_QueryInterface(mSecInfo);
     if (secCtrl)
         secCtrl->SetNotificationCallbacks(nsnull);
 
@@ -1594,7 +1591,7 @@ nsSocketTransport::OpenInputStream(PRUin
     NS_ENSURE_TRUE(!mInput.IsReferenced(), NS_ERROR_UNEXPECTED);
 
     nsresult rv;
-    nsCOMPtr<nsIAsyncInputStream> pipeIn;
+    nsIAsyncInputStream* pipeIn = nsnull;
 
     if (!(flags & OPEN_UNBUFFERED) || (flags & OPEN_BLOCKING)) {
         // XXX if the caller wants blocking, then the caller also gets buffered!
@@ -1605,8 +1602,8 @@ nsSocketTransport::OpenInputStream(PRUin
         nsIMemory *segalloc = net_GetSegmentAlloc(segsize);
 
         // create a pipe
-        nsCOMPtr<nsIAsyncOutputStream> pipeOut;
-        rv = NS_NewPipe2(getter_AddRefs(pipeIn), getter_AddRefs(pipeOut),
+        nsIAsyncOutputStream* pipeOut = nsnull;
+        rv = NS_NewPipe2(&pipeIn, &pipeOut,
                          !openBlocking, PR_TRUE, segsize, segcount, segalloc);
         if (NS_FAILED(rv)) return rv;
 
@@ -1626,7 +1623,6 @@ nsSocketTransport::OpenInputStream(PRUin
     rv = PostEvent(MSG_ENSURE_CONNECT);
     if (NS_FAILED(rv)) return rv;
 
-    NS_ADDREF(*result);
     return NS_OK;
 }
 
@@ -1642,7 +1638,7 @@ nsSocketTransport::OpenOutputStream(PRUi
     NS_ENSURE_TRUE(!mOutput.IsReferenced(), NS_ERROR_UNEXPECTED);
 
     nsresult rv;
-    nsCOMPtr<nsIAsyncOutputStream> pipeOut;
+    nsIAsyncOutputStream* pipeOut = nsnull;
     if (!(flags & OPEN_UNBUFFERED) || (flags & OPEN_BLOCKING)) {
         // XXX if the caller wants blocking, then the caller also gets buffered!
         //PRBool openBuffered = !(flags & OPEN_UNBUFFERED);
@@ -1652,8 +1648,8 @@ nsSocketTransport::OpenOutputStream(PRUi
         nsIMemory *segalloc = net_GetSegmentAlloc(segsize);
 
         // create a pipe
-        nsCOMPtr<nsIAsyncInputStream> pipeIn;
-        rv = NS_NewPipe2(getter_AddRefs(pipeIn), getter_AddRefs(pipeOut),
+        nsIAsyncInputStream* pipeIn = nsnull;
+        rv = NS_NewPipe2(&pipeIn, &pipeOut,
                          PR_TRUE, !openBlocking, segsize, segcount, segalloc);
         if (NS_FAILED(rv)) return rv;
 
@@ -1673,7 +1669,6 @@ nsSocketTransport::OpenOutputStream(PRUi
     rv = PostEvent(MSG_ENSURE_CONNECT);
     if (NS_FAILED(rv)) return rv;
 
-    NS_ADDREF(*result);
     return NS_OK;
 }
 
@@ -1692,7 +1687,7 @@ nsSocketTransport::GetSecurityInfo(nsISu
 nsSocketTransport::GetSecurityInfo(nsISupports **secinfo)
 {
     nsAutoLock lock(mLock);
-    NS_IF_ADDREF(*secinfo = mSecInfo);
+    *secinfo = mSecInfo;
     return NS_OK;
 }
 
@@ -1700,7 +1695,7 @@ nsSocketTransport::GetSecurityCallbacks(
 nsSocketTransport::GetSecurityCallbacks(nsIInterfaceRequestor **callbacks)
 {
     nsAutoLock lock(mLock);
-    NS_IF_ADDREF(*callbacks = mCallbacks);
+    *callbacks = mCallbacks;
     return NS_OK;
 }
 
@@ -1717,13 +1712,13 @@ nsSocketTransport::SetEventSink(nsITrans
 nsSocketTransport::SetEventSink(nsITransportEventSink *sink,
                                 nsIEventTarget *target)
 {
-    nsCOMPtr<nsITransportEventSink> temp;
+    nsITransportEventSink* temp = nsnull;
     if (target) {
-        nsresult rv = net_NewTransportEventSinkProxy(getter_AddRefs(temp),
+        nsresult rv = net_NewTransportEventSinkProxy(&temp,
                                                      sink, target);
         if (NS_FAILED(rv))
             return rv;
-        sink = temp.get();
+        sink = temp;
     }
 
     nsAutoLock lock(mLock);
diff --git a/netwerk/base/src/nsSocketTransportService2.cpp b/netwerk/base/src/nsSocketTransportService2.cpp
--- a/netwerk/base/src/nsSocketTransportService2.cpp
+++ b/netwerk/base/src/nsSocketTransportService2.cpp
@@ -83,7 +83,6 @@ nsSocketTransportService::nsSocketTransp
 
 nsSocketTransportService::~nsSocketTransportService()
 {
-    NS_ASSERTION(NS_IsMainThread(), "wrong thread");
     NS_ASSERTION(!mInitialized, "not shutdown properly");
 
     if (mLock)
@@ -340,6 +339,9 @@ nsSocketTransportService::Poll(PRBool wa
 
     if (!wait)
         pollTimeout = PR_INTERVAL_NO_WAIT;
+
+    if (pollTimeout > PR_MillisecondsToInterval(25))
+      pollTimeout = PR_MillisecondsToInterval(25);
 
     PRInt32 rv;
     PRIntervalTime ts;
diff --git a/netwerk/base/src/nsStreamListenerTee.cpp b/netwerk/base/src/nsStreamListenerTee.cpp
--- a/netwerk/base/src/nsStreamListenerTee.cpp
+++ b/netwerk/base/src/nsStreamListenerTee.cpp
@@ -58,6 +58,7 @@ nsStreamListenerTee::OnStopRequest(nsIRe
     NS_ENSURE_TRUE(mListener, NS_ERROR_NOT_INITIALIZED);
     // it is critical that we close out the input stream tee
     if (mInputTee) {
+        mInputTee->Close();
         mInputTee->SetSink(nsnull);
         mInputTee = 0;
     }
@@ -75,11 +76,11 @@ nsStreamListenerTee::OnDataAvailable(nsI
     NS_ENSURE_TRUE(mListener, NS_ERROR_NOT_INITIALIZED);
     NS_ENSURE_TRUE(mSink, NS_ERROR_NOT_INITIALIZED);
 
-    nsCOMPtr<nsIInputStream> tee;
     nsresult rv;
 
     if (!mInputTee) {
-        rv = NS_NewInputStreamTee(getter_AddRefs(tee), input, mSink);
+        nsIInputStream *tee = nsnull;
+        rv = NS_NewInputStreamTee(&tee, input, mSink);
         if (NS_FAILED(rv)) return rv;
 
         mInputTee = do_QueryInterface(tee, &rv);
@@ -89,12 +90,9 @@ nsStreamListenerTee::OnDataAvailable(nsI
         // re-initialize the input tee since the input stream may have changed.
         rv = mInputTee->SetSource(input);
         if (NS_FAILED(rv)) return rv;
-
-        tee = do_QueryInterface(mInputTee, &rv);
-        if (NS_FAILED(rv)) return rv;
     }
 
-    return mListener->OnDataAvailable(request, context, tee, offset, count);
+    return mListener->OnDataAvailable(request, context, mInputTee, offset, count);
 }
 
 NS_IMETHODIMP
diff --git a/netwerk/cache/src/nsCacheDevice.h b/netwerk/cache/src/nsCacheDevice.h
--- a/netwerk/cache/src/nsCacheDevice.h
+++ b/netwerk/cache/src/nsCacheDevice.h
@@ -55,7 +55,7 @@ class nsIOutputStream;
 /******************************************************************************
 * nsCacheDevice
 *******************************************************************************/
-class nsCacheDevice {
+class nsCacheDevice : public XPCOMGCFinalizedObject, MMgc::GCFinalizable {
 public:
     nsCacheDevice() { MOZ_COUNT_CTOR(nsCacheDevice); }
     virtual ~nsCacheDevice() { MOZ_COUNT_DTOR(nsCacheDevice); }
diff --git a/netwerk/cache/src/nsCacheEntry.cpp b/netwerk/cache/src/nsCacheEntry.cpp
--- a/netwerk/cache/src/nsCacheEntry.cpp
+++ b/netwerk/cache/src/nsCacheEntry.cpp
@@ -80,9 +80,6 @@ nsCacheEntry::~nsCacheEntry()
 {
     MOZ_COUNT_DTOR(nsCacheEntry);
     delete mKey;
-    
-    if (mData)
-        nsCacheService::ReleaseObject_Locked(mData, mThread);
 }
 
 
@@ -128,21 +125,6 @@ nsCacheEntry::TouchData()
 {
     mLastModified = SecondsFromPRTime(PR_Now());
     MarkDataDirty();
-}
-
-
-void
-nsCacheEntry::SetData(nsISupports * data)
-{
-    if (mData) {
-        nsCacheService::ReleaseObject_Locked(mData, mThread);
-        mData = nsnull;
-    }
-
-    if (data) {
-        NS_ADDREF(mData = data);
-        mThread = do_GetCurrentThread();
-    }
 }
 
 
@@ -225,7 +207,7 @@ nsCacheEntry::CreateDescriptor(nsCacheRe
 
     PR_APPEND_LINK(descriptor, &mDescriptorQ);
 
-    NS_ADDREF(*result = descriptor);
+    *result = descriptor;
     return NS_OK;
 }
 
@@ -386,8 +368,8 @@ PLDHashTableOps
 PLDHashTableOps
 nsCacheEntryHashTable::ops =
 {
-    PL_DHashAllocTable,
-    PL_DHashFreeTable,
+    GCAllocTable,
+    GCFreeTable,
     HashKey,
     MatchEntry,
     MoveEntry,
diff --git a/netwerk/cache/src/nsCacheEntry.h b/netwerk/cache/src/nsCacheEntry.h
--- a/netwerk/cache/src/nsCacheEntry.h
+++ b/netwerk/cache/src/nsCacheEntry.h
@@ -63,7 +63,9 @@ class nsCacheEntryDescriptor;
 /******************************************************************************
 * nsCacheEntry
 *******************************************************************************/
-class nsCacheEntry : public PRCList
+class nsCacheEntry : public XPCOMGCFinalizedObject
+                   , public MMgc::GCFinalizable
+                   , public PRCList
 {
 public:
 
@@ -72,6 +74,11 @@ public:
                  nsCacheStoragePolicy storagePolicy);
     ~nsCacheEntry();
 
+    // it's ok to explicitly delete this
+    static void operator delete(void* obj)
+    {
+        return XPCOMGCFinalizedObject::operator delete(obj);
+    }
 
     static nsresult  Create( const char *          key,
                              PRBool                streamBased,
@@ -104,7 +111,7 @@ public:
      * Data accessors
      */
     nsISupports *Data()                           { return mData; }
-    void         SetData( nsISupports * data);
+    void         SetData(nsISupports * data)      { mData = data; }
 
     PRUint32 DataSize()                           { return mDataSize; }
     void     SetDataSize( PRUint32  size)         { mDataSize = size; }
@@ -244,8 +251,7 @@ private:
     PRUint32                mDataSize;       // 4
     nsCacheDevice *         mCacheDevice;    // 4
     nsCOMPtr<nsISupports>   mSecurityInfo;   // 
-    nsISupports *           mData;           // strong ref
-    nsCOMPtr<nsIThread>     mThread;
+    nsCOMPtr<nsISupports>   mData;
     nsCacheMetaData         mMetaData;       // 4
     PRCList                 mRequestQ;       // 8
     PRCList                 mDescriptorQ;    // 8
@@ -255,7 +261,7 @@ private:
 /******************************************************************************
 * nsCacheEntryInfo
 *******************************************************************************/
-class nsCacheEntryInfo : public nsICacheEntryInfo {
+class nsCacheEntryInfo : public XPCOMGCFinalizedObject, public nsICacheEntryInfo {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSICACHEENTRYINFO
diff --git a/netwerk/cache/src/nsCacheEntryDescriptor.cpp b/netwerk/cache/src/nsCacheEntryDescriptor.cpp
--- a/netwerk/cache/src/nsCacheEntryDescriptor.cpp
+++ b/netwerk/cache/src/nsCacheEntryDescriptor.cpp
@@ -57,22 +57,11 @@ nsCacheEntryDescriptor::nsCacheEntryDesc
       mAccessGranted(accessGranted)
 {
     PR_INIT_CLIST(this);
-    NS_ADDREF(nsCacheService::GlobalInstance());  // ensure it lives for the lifetime of the descriptor
 }
 
 
 nsCacheEntryDescriptor::~nsCacheEntryDescriptor()
 {
-    // No need to close if the cache entry has already been severed.  This
-    // helps avoid a shutdown assertion (bug 285519) that is caused when
-    // consumers end up holding onto these objects past xpcom-shutdown.  It's
-    // okay for them to do that because the cache service calls our Close
-    // method during xpcom-shutdown, so we don't need to complain about it.
-    if (mCacheEntry)
-        Close();
-
-    nsCacheService * service = nsCacheService::GlobalInstance();
-    NS_RELEASE(service);
 }
 
 
@@ -254,7 +243,7 @@ nsCacheEntryDescriptor::OpenInputStream(
         new nsInputStreamWrapper(this, offset);
     if (!cacheInput) return NS_ERROR_OUT_OF_MEMORY;
 
-    NS_ADDREF(*result = cacheInput);
+    *result = cacheInput;
     return NS_OK;
 }
 
@@ -277,7 +266,7 @@ nsCacheEntryDescriptor::OpenOutputStream
         new nsOutputStreamWrapper(this, offset);
     if (!cacheOutput) return NS_ERROR_OUT_OF_MEMORY;
 
-    NS_ADDREF(*result = cacheOutput);
+    *result = cacheOutput;
     return NS_OK;
 }
 
@@ -290,7 +279,7 @@ nsCacheEntryDescriptor::GetCacheElement(
     if (!mCacheEntry)                 return NS_ERROR_NOT_AVAILABLE;
     if (mCacheEntry->IsStreamData())  return NS_ERROR_CACHE_DATA_IS_STREAM;
 
-    NS_IF_ADDREF(*result = mCacheEntry->Data());
+    *result = mCacheEntry->Data();
     return NS_OK;
 }
 
@@ -507,7 +496,7 @@ nsInputStreamWrapper::LazyInit()
     nsCacheEntry* cacheEntry = mDescriptor->CacheEntry();
     if (!cacheEntry) return NS_ERROR_NOT_AVAILABLE;
 
-    nsCOMPtr<nsIInputStream> input;
+    nsIInputStream* input = nsnull;
     rv = nsCacheService::OpenInputStreamForEntry(cacheEntry, mode,
                                                  mStartOffset,
                                                  getter_AddRefs(mInput));
diff --git a/netwerk/cache/src/nsCacheEntryDescriptor.h b/netwerk/cache/src/nsCacheEntryDescriptor.h
--- a/netwerk/cache/src/nsCacheEntryDescriptor.h
+++ b/netwerk/cache/src/nsCacheEntryDescriptor.h
@@ -51,8 +51,9 @@
 * nsCacheEntryDescriptor
 *******************************************************************************/
 class nsCacheEntryDescriptor :
-    public PRCList,
-    public nsICacheEntryDescriptor
+    public XPCOMGCFinalizedObject,
+    public nsICacheEntryDescriptor,
+    public PRCList
 {
 public:
     NS_DECL_ISUPPORTS
@@ -82,7 +83,7 @@ private:
       * The input stream wrapper references the descriptor, but the descriptor
       * doesn't need any references to the stream wrapper.
       *************************************************************************/
-     class nsInputStreamWrapper : public nsIInputStream {
+     class nsInputStreamWrapper : public XPCOMGCFinalizedObject, public nsIInputStream {
      private:
          nsCacheEntryDescriptor    * mDescriptor;
          nsCOMPtr<nsIInputStream>    mInput;
@@ -97,7 +98,6 @@ private:
              , mStartOffset(off)
              , mInitialized(PR_FALSE)
          {
-             NS_ADDREF(mDescriptor);
          }
          virtual ~nsInputStreamWrapper()
          {
@@ -117,7 +117,7 @@ private:
       * The output stream wrapper references the descriptor, but the descriptor
       * doesn't need any references to the stream wrapper.
       *************************************************************************/
-     class nsOutputStreamWrapper : public nsIOutputStream {
+     class nsOutputStreamWrapper : public XPCOMGCFinalizedObject, public nsIOutputStream {
      private:
          nsCacheEntryDescriptor *    mDescriptor;
          nsCOMPtr<nsIOutputStream>   mOutput;
@@ -132,7 +132,6 @@ private:
              , mStartOffset(off)
              , mInitialized(PR_FALSE)
          {
-             NS_ADDREF(mDescriptor); // owning ref
          }
          virtual ~nsOutputStreamWrapper()
          { 
diff --git a/netwerk/cache/src/nsCacheRequest.h b/netwerk/cache/src/nsCacheRequest.h
--- a/netwerk/cache/src/nsCacheRequest.h
+++ b/netwerk/cache/src/nsCacheRequest.h
@@ -49,7 +49,9 @@
 #include "nsCacheService.h"
 
 
-class nsCacheRequest : public PRCList
+class nsCacheRequest : public XPCOMGCFinalizedObject
+                     , public MMgc::GCFinalizable
+                     , public PRCList
 {
 private:
     friend class nsCacheService;
@@ -74,7 +76,6 @@ private:
         if (session->WillDoomEntriesIfExpired())  MarkDoomEntriesIfExpired();
         if (blockingMode == nsICache::BLOCKING)    MarkBlockingMode();
         MarkWaitingForValidation();
-        NS_IF_ADDREF(mListener);
     }
     
     ~nsCacheRequest()
@@ -83,12 +84,13 @@ private:
         delete mKey;
         if (mLock)    PR_DestroyLock(mLock);
         if (mCondVar) PR_DestroyCondVar(mCondVar);
-        NS_ASSERTION(PR_CLIST_IS_EMPTY(this), "request still on a list");
+    }
 
-        if (mListener)
-            nsCacheService::ReleaseObject_Locked(mListener, mThread);
+    static void operator delete(void *obj)
+    {
+        NS_GetGC()->Free(obj);
     }
-    
+
     /**
      * Simple Accessors
      */
diff --git a/netwerk/cache/src/nsCacheService.cpp b/netwerk/cache/src/nsCacheService.cpp
--- a/netwerk/cache/src/nsCacheService.cpp
+++ b/netwerk/cache/src/nsCacheService.cpp
@@ -111,7 +111,7 @@ static const char * prefList[] = {
     MEMORY_CACHE_CAPACITY_PREF
 };
 
-class nsCacheProfilePrefObserver : public nsIObserver
+class nsCacheProfilePrefObserver : public XPCOMGCFinalizedObject, public nsIObserver
 {
 public:
     NS_DECL_ISUPPORTS
@@ -181,7 +181,7 @@ nsCacheProfilePrefObserver::Install()
     
     
     // install preferences observer
-    nsCOMPtr<nsIPrefBranch2> branch = do_GetService(NS_PREFSERVICE_CONTRACTID);
+    nsIPrefBranch2* branch = do_GetService(NS_PREFSERVICE_CONTRACTID);
     if (!branch) return NS_ERROR_FAILURE;
 
     for (int i=0; i<NS_ARRAY_LENGTH(prefList); i++) {
@@ -197,9 +197,9 @@ nsCacheProfilePrefObserver::Install()
     //     In that case, we detect the presence of a profile by the existence
     //     of the NS_APP_USER_PROFILE_50_DIR directory.
 
-    nsCOMPtr<nsIFile>  directory;
+    nsIFile*  directory = nsnull;
     rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
-                                getter_AddRefs(directory));
+                                &directory);
     if (NS_SUCCEEDED(rv)) {
         mHaveProfile = PR_TRUE;
     }
@@ -215,7 +215,7 @@ nsCacheProfilePrefObserver::Remove()
 nsCacheProfilePrefObserver::Remove()
 {
     // remove Observer Service observers
-    nsCOMPtr<nsIObserverService> obs =
+    nsIObserverService* obs =
             do_GetService("@mozilla.org/observer-service;1");
     if (obs) {
         for (int i=0; i<NS_ARRAY_LENGTH(observerList); i++) {
@@ -224,7 +224,7 @@ nsCacheProfilePrefObserver::Remove()
     }
 
     // remove Pref Service observers
-    nsCOMPtr<nsIPrefBranch2> prefs =
+    nsIPrefBranch2* prefs =
            do_GetService(NS_PREFSERVICE_CONTRACTID);
     if (prefs) {
         for (int i=0; i<NS_ARRAY_LENGTH(prefList); i++) {
@@ -260,7 +260,7 @@ nsCacheProfilePrefObserver::Observe(nsIS
     } else if (!strcmp("profile-after-change", topic)) {
         // profile after change
         mHaveProfile = PR_TRUE;
-        nsCOMPtr<nsIPrefBranch> branch = do_GetService(NS_PREFSERVICE_CONTRACTID);
+        nsIPrefBranch* branch = do_GetService(NS_PREFSERVICE_CONTRACTID);
         ReadPrefs(branch);
         nsCacheService::OnProfileChanged();
     
@@ -269,7 +269,7 @@ nsCacheProfilePrefObserver::Observe(nsIS
         // ignore pref changes until we're done switch profiles
         if (!mHaveProfile)  return NS_OK;
 
-        nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(subject, &rv);
+        nsIPrefBranch* branch = do_QueryInterface(subject, &rv);
         if (NS_FAILED(rv))  return rv;
 
 #ifdef NECKO_DISK_CACHE
@@ -363,18 +363,18 @@ nsCacheProfilePrefObserver::ReadPrefs(ns
                                    getter_AddRefs(mDiskCacheParentDirectory));
     
     if (!mDiskCacheParentDirectory) {
-        nsCOMPtr<nsIFile>  directory;
+        nsIFile*  directory = nsnull;
 
         // try to get the disk cache parent directory
         rv = NS_GetSpecialDirectory(NS_APP_CACHE_PARENT_DIR,
-                                    getter_AddRefs(directory));
+                                    &directory);
         if (NS_FAILED(rv)) {
             // try to get the profile directory (there may not be a profile yet)
-            nsCOMPtr<nsIFile> profDir;
+            nsIFile* profDir = nsnull;
             NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
-                                   getter_AddRefs(profDir));
+                                   &profDir);
             NS_GetSpecialDirectory(NS_APP_USER_PROFILE_LOCAL_50_DIR,
-                                   getter_AddRefs(directory));
+                                   &directory);
             if (!directory)
                 directory = profDir;
             else if (profDir) {
@@ -395,7 +395,7 @@ nsCacheProfilePrefObserver::ReadPrefs(ns
         if (!directory) {
             // use current process directory during development
             rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
-                                        getter_AddRefs(directory));
+                                        &directory);
         }
 #endif
         if (directory)
@@ -419,18 +419,18 @@ nsCacheProfilePrefObserver::ReadPrefs(ns
                                    getter_AddRefs(mOfflineCacheParentDirectory));
 
     if (!mOfflineCacheParentDirectory) {
-        nsCOMPtr<nsIFile>  directory;
+        nsIFile*  directory = nsnull;
 
         // try to get the offline cache parent directory
         rv = NS_GetSpecialDirectory(NS_APP_CACHE_PARENT_DIR,
-                                    getter_AddRefs(directory));
+                                    &directory);
         if (NS_FAILED(rv)) {
             // try to get the profile directory (there may not be a profile yet)
-            nsCOMPtr<nsIFile> profDir;
+            nsIFile* profDir = nsnull;
             NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
-                                   getter_AddRefs(profDir));
+                                   &profDir);
             NS_GetSpecialDirectory(NS_APP_USER_PROFILE_LOCAL_50_DIR,
-                                   getter_AddRefs(directory));
+                                   &directory);
             if (!directory)
                 directory = profDir;
         }
@@ -438,7 +438,7 @@ nsCacheProfilePrefObserver::ReadPrefs(ns
         if (!directory) {
             // use current process directory during development
             rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR,
-                                        getter_AddRefs(directory));
+                                        &directory);
         }
 #endif
         if (directory)
@@ -623,7 +623,6 @@ nsCacheService::Init()
     // create profile/preference observer
     mObserver = new nsCacheProfilePrefObserver();
     if (!mObserver)  return NS_ERROR_OUT_OF_MEMORY;
-    NS_ADDREF(mObserver);
     
     mObserver->Install();
     mEnableDiskDevice    = mObserver->DiskCacheEnabled();
@@ -653,17 +652,12 @@ nsCacheService::Shutdown()
         ClearDoomList();
         ClearActiveEntries();
 
-        // deallocate memory and disk caches
-        delete mMemoryDevice;
+        // lose the memory and disk caches
         mMemoryDevice = nsnull;
-
 #ifdef NECKO_DISK_CACHE
-        delete mDiskDevice;
         mDiskDevice = nsnull;
 #endif // !NECKO_DISK_CACHE
-
 #ifdef NECKO_OFFLINE_CACHE
-        delete mOfflineDevice;
         mOfflineDevice = nsnull;
 #endif // !NECKO_OFFLINE_CACHE
 
@@ -686,7 +680,6 @@ nsCacheService::Create(nsISupports* aOut
     if (cacheService == nsnull)
         return NS_ERROR_OUT_OF_MEMORY;
 
-    NS_ADDREF(cacheService);
     rv = cacheService->Init();
     if (NS_SUCCEEDED(rv)) {
         rv = cacheService->QueryInterface(aIID, aResult);
@@ -709,7 +702,7 @@ nsCacheService::CreateSession(const char
     nsCacheSession * session = new nsCacheSession(clientID, storagePolicy, streamBased);
     if (!session)  return NS_ERROR_OUT_OF_MEMORY;
 
-    NS_ADDREF(*result = session);
+    *result = session;
 
     return NS_OK;
 }
@@ -730,17 +723,17 @@ nsCacheService::EvictEntriesForClient(co
 {
     if (this == nsnull) return NS_ERROR_NOT_AVAILABLE; // XXX eh?
 
-    nsCOMPtr<nsIObserverService> obsSvc =
+    nsIObserverService* obsSvc =
         do_GetService("@mozilla.org/observer-service;1");
     if (obsSvc) {
         // Proxy to the UI thread since the observer service isn't thredsafe.
         // We use an async proxy, since this it's not important whether this
         // notification happens before or after the actual eviction.
 
-        nsCOMPtr<nsIObserverService> obsProxy;
+        nsIObserverService* obsProxy = nsnull;
         NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
                              NS_GET_IID(nsIObserverService), obsSvc,
-                             NS_PROXY_ASYNC, getter_AddRefs(obsProxy));
+                             NS_PROXY_ASYNC, (void**)&obsProxy);
 
         if (obsProxy) {
             obsProxy->NotifyObservers(this,
@@ -1260,7 +1253,7 @@ nsCacheService::CreateRequest(nsCacheSes
 
     // get the request's thread
     (*request)->mThread = do_GetCurrentThread();
-    
+
     return NS_OK;
 }
 
@@ -1311,7 +1304,7 @@ nsCacheService::NotifyListener(nsCacheRe
     nsICacheListener *listener = request->mListener;
     request->mListener = nsnull;
 
-    nsCOMPtr<nsIRunnable> ev =
+    nsIRunnable* ev =
             new nsCacheListenerEvent(listener, descriptor,
                                      accessGranted, status);
     if (!ev) {
diff --git a/netwerk/cache/src/nsDeleteDir.cpp b/netwerk/cache/src/nsDeleteDir.cpp
--- a/netwerk/cache/src/nsDeleteDir.cpp
+++ b/netwerk/cache/src/nsDeleteDir.cpp
@@ -40,22 +40,35 @@
 #include "nsIFile.h"
 #include "nsString.h"
 #include "prthread.h"
+#include "nsXPCOMRequests.h"
+
+struct RootFile : MMgc::GCRoot
+{
+  RootFile(nsIFile* file)
+    : MMgc::GCRoot(NS_GetGC())
+    , mFile(file)
+  { }
+
+  nsIFile *mFile;
+};
 
 PR_STATIC_CALLBACK(void) DeleteDirThreadFunc(void *arg)
 {
-  nsIFile *dir = static_cast<nsIFile *>(arg);
-  dir->Remove(PR_TRUE);
-  NS_RELEASE(dir);
+  RootFile *dir = static_cast<RootFile *>(arg);
+  NS_BeginRequest();
+  dir->mFile->Remove(PR_TRUE);
+  delete dir;
+  NS_EndRequest();
 }
 
 nsresult DeleteDir(nsIFile *dirIn, PRBool moveToTrash, PRBool sync)
 {
   nsresult rv;
-  nsCOMPtr<nsIFile> trash, dir;
+  nsIFile* trash = nsnull, *dir = nsnull;
 
   // Need to make a clone of this since we don't want to modify the input
   // file object.
-  rv = dirIn->Clone(getter_AddRefs(dir));
+  rv = dirIn->Clone(&dir);
   if (NS_FAILED(rv))
     return rv;
 
@@ -65,8 +78,8 @@ nsresult DeleteDir(nsIFile *dirIn, PRBoo
     if (NS_FAILED(rv))
       return rv;
 
-    nsCOMPtr<nsIFile> subDir;
-    rv = trash->Clone(getter_AddRefs(subDir));
+    nsIFile* subDir = nsnull;
+    rv = trash->Clone(&subDir);
     if (NS_FAILED(rv))
       return rv;
 
@@ -85,12 +98,11 @@ nsresult DeleteDir(nsIFile *dirIn, PRBoo
   else
   {
     // we want to pass a clone of the original off to the worker thread.
-    trash.swap(dir);
+    swap(trash, dir);
   }
 
-  // Steal ownership of trash directory; let the thread release it.
-  nsIFile *trashRef = nsnull;
-  trash.swap(trashRef);
+  // Root the trash directory: the thread will delete the root
+  RootFile *trashRef = new RootFile(trash);
 
   if (sync)
   {
@@ -113,9 +125,9 @@ nsresult DeleteDir(nsIFile *dirIn, PRBoo
   return NS_OK;
 }
 
-nsresult GetTrashDir(nsIFile *target, nsCOMPtr<nsIFile> *result)
+nsresult GetTrashDir(nsIFile *target, nsIFile* *result)
 {
-  nsresult rv = target->Clone(getter_AddRefs(*result));
+  nsresult rv = target->Clone(&*result);
   if (NS_FAILED(rv))
     return rv;
 
diff --git a/netwerk/cache/src/nsDeleteDir.h b/netwerk/cache/src/nsDeleteDir.h
--- a/netwerk/cache/src/nsDeleteDir.h
+++ b/netwerk/cache/src/nsDeleteDir.h
@@ -66,6 +66,6 @@ NS_HIDDEN_(nsresult) DeleteDir(nsIFile *
  * This routine returns the trash directory corresponding to the given 
  * directory.
  */
-NS_HIDDEN_(nsresult) GetTrashDir(nsIFile *dir, nsCOMPtr<nsIFile> *result);
+NS_HIDDEN_(nsresult) GetTrashDir(nsIFile *dir, nsIFile **result);
 
 #endif  // nsDeleteDir_h__
diff --git a/netwerk/cache/src/nsDiskCacheDevice.cpp b/netwerk/cache/src/nsDiskCacheDevice.cpp
--- a/netwerk/cache/src/nsDiskCacheDevice.cpp
+++ b/netwerk/cache/src/nsDiskCacheDevice.cpp
@@ -156,7 +156,7 @@ nsDiskCacheEvictor::VisitRecord(nsDiskCa
  *  nsDiskCacheDeviceInfo
  *****************************************************************************/
 
-class nsDiskCacheDeviceInfo : public nsICacheDeviceInfo {
+class nsDiskCacheDeviceInfo : public XPCOMGCFinalizedObject, public nsICacheDeviceInfo {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSICACHEDEVICEINFO
@@ -189,9 +189,9 @@ NS_IMETHODIMP nsDiskCacheDeviceInfo::Get
     nsCString buffer;
     
     buffer.AssignLiteral("\n<tr>\n<td><b>Cache Directory:</b></td>\n<td><tt> ");
-    nsCOMPtr<nsILocalFile> cacheDir;
+    nsILocalFile* cacheDir = nsnull;
     nsAutoString           path;
-    mDevice->getCacheDirectory(getter_AddRefs(cacheDir)); 
+    mDevice->getCacheDirectory(&cacheDir); 
     nsresult rv = cacheDir->GetPath(path);
     if (NS_SUCCEEDED(rv)) {
         AppendUTF16toUTF8(path, buffer);
@@ -343,7 +343,7 @@ nsDiskCacheDevice::Shutdown()
 
     if (mCacheDirectory) {
         // delete any trash files left-over before shutting down.
-        nsCOMPtr<nsIFile> trashDir;
+        nsIFile* trashDir = nsnull;
         GetTrashDir(mCacheDirectory, &trashDir);
         if (trashDir) {
             PRBool exists;
@@ -466,7 +466,6 @@ nsDiskCacheDevice::DeactivateEntry(nsCac
     }
 
     mBindery.RemoveBinding(binding); // extract binding from collision detection stuff
-    delete entry;   // which will release binding
     return rv;
 }
 
@@ -647,13 +646,13 @@ nsDiskCacheDevice::GetFileForEntry(nsCac
         }
     }
     
-    nsCOMPtr<nsIFile>  file;
+    nsIFile*  file = nsnull;
     rv = mCacheMap.GetFileForDiskCacheRecord(&binding->mRecord,
                                              nsDiskCache::kData,
-                                             getter_AddRefs(file));
+                                             &file);
     if (NS_FAILED(rv))  return rv;
     
-    NS_IF_ADDREF(*result = file);
+    *result = file;
     return NS_OK;
 }
 
@@ -732,7 +731,7 @@ public:
         if (!entryInfo) {
             return kStopVisitingRecords;
         }
-        nsCOMPtr<nsICacheEntryInfo> ref(entryInfo);
+        nsICacheEntryInfo* ref(entryInfo);
         
         PRBool  keepGoing;
         (void)mVisitor->VisitEntry(DISK_CACHE_DEVICE_ID, entryInfo, &keepGoing);
@@ -750,7 +749,7 @@ nsDiskCacheDevice::Visit(nsICacheVisitor
 {
     if (!Initialized())  return NS_ERROR_NOT_INITIALIZED;
     nsDiskCacheDeviceInfo* deviceInfo = new nsDiskCacheDeviceInfo(this);
-    nsCOMPtr<nsICacheDeviceInfo> ref(deviceInfo);
+    nsICacheDeviceInfo* ref(deviceInfo);
     
     PRBool keepGoing;
     nsresult rv = visitor->VisitDevice(DISK_CACHE_DEVICE_ID, deviceInfo, &keepGoing);
@@ -834,7 +833,7 @@ nsDiskCacheDevice::OpenDiskCache()
 
     if (!trashing) {
         // delete any trash files leftover from a previous run
-        nsCOMPtr<nsIFile> trashDir;
+        nsIFile* trashDir = nsnull;
         GetTrashDir(mCacheDirectory, &trashDir);
         if (trashDir) {
             PRBool exists;
@@ -911,9 +910,9 @@ nsDiskCacheDevice::SetCacheParentDirecto
     if (NS_FAILED(rv))  return;
 
     // ensure cache directory exists
-    nsCOMPtr<nsIFile> directory;
+    nsIFile* directory = nsnull;
     
-    rv = parentDir->Clone(getter_AddRefs(directory));
+    rv = parentDir->Clone(&directory);
     if (NS_FAILED(rv))  return;
     rv = directory->AppendNative(NS_LITERAL_CSTRING("Cache"));
     if (NS_FAILED(rv))  return;
@@ -926,7 +925,6 @@ nsDiskCacheDevice::getCacheDirectory(nsI
 nsDiskCacheDevice::getCacheDirectory(nsILocalFile ** result)
 {
     *result = mCacheDirectory;
-    NS_IF_ADDREF(*result);
 }
 
 
diff --git a/netwerk/cache/src/nsDiskCacheStreams.cpp b/netwerk/cache/src/nsDiskCacheStreams.cpp
--- a/netwerk/cache/src/nsDiskCacheStreams.cpp
+++ b/netwerk/cache/src/nsDiskCacheStreams.cpp
@@ -59,7 +59,7 @@
 #ifdef XP_MAC
 #pragma mark nsDiskCacheInputStream
 #endif
-class nsDiskCacheInputStream : public nsIInputStream {
+class nsDiskCacheInputStream : public XPCOMGCFinalizedObject, public nsIInputStream {
 
 public:
 
@@ -97,7 +97,6 @@ nsDiskCacheInputStream::nsDiskCacheInput
     , mPos(0)
     , mClosed(PR_FALSE)
 {
-    NS_ADDREF(mStreamIO);
     mStreamIO->IncrementInputStreamCount();
 }
 
@@ -195,7 +194,7 @@ nsDiskCacheInputStream::IsNonBlocking(PR
 #pragma mark -
 #pragma mark nsDiskCacheOutputStream
 #endif
-class nsDiskCacheOutputStream : public nsIOutputStream {
+class nsDiskCacheOutputStream : public XPCOMGCFinalizedObject, public nsIOutputStream {
 public:
     nsDiskCacheOutputStream( nsDiskCacheStreamIO * parent);
     virtual ~nsDiskCacheOutputStream();
@@ -206,7 +205,7 @@ public:
     void ReleaseStreamIO() { NS_IF_RELEASE(mStreamIO); }
 
 private:
-    nsDiskCacheStreamIO *           mStreamIO;  // backpointer to parent
+    nsCOMPtr<nsDiskCacheStreamIO>   mStreamIO;  // backpointer to parent
     PRBool                          mClosed;
 };
 
@@ -218,7 +217,6 @@ nsDiskCacheOutputStream::nsDiskCacheOutp
     : mStreamIO(parent)
     , mClosed(PR_FALSE)
 {
-    NS_ADDREF(mStreamIO);
 }
 
 
@@ -245,8 +243,8 @@ nsDiskCacheOutputStream::Flush()
 nsDiskCacheOutputStream::Flush()
 {
     if (mClosed)  return NS_BASE_STREAM_CLOSED;
-    // yeah, yeah, well get to it...eventually...
-    return NS_OK;
+
+    return mStreamIO->Flush();
 }
 
 
@@ -318,17 +316,12 @@ nsDiskCacheStreamIO::nsDiskCacheStreamIO
 
     // acquire "death grip" on cache service
     nsCacheService *service = nsCacheService::GlobalInstance();
-    NS_ADDREF(service);
 }
 
 
 nsDiskCacheStreamIO::~nsDiskCacheStreamIO()
 {
     Close();
-
-    // release "death grip" on cache service
-    nsCacheService *service = nsCacheService::GlobalInstance();
-    NS_RELEASE(service);
 }
 
 
@@ -339,7 +332,6 @@ nsDiskCacheStreamIO::Close()
     // no one is interested in us anymore, so we don't need to grab any locks
     
     // assert streams closed
-    NS_ASSERTION(!mOutStream, "output stream still open");
     NS_ASSERTION(mInStreamCount == 0, "input stream still open");
     NS_ASSERTION(!mFD, "file descriptor not closed");
 
@@ -390,7 +382,7 @@ nsDiskCacheStreamIO::GetInputStream(PRUi
     nsDiskCacheInputStream * inStream = new nsDiskCacheInputStream(this, fd, mBuffer, mStreamEnd);
     if (!inStream)  return NS_ERROR_OUT_OF_MEMORY;
     
-    NS_ADDREF(*inputStream = inStream);
+    *inputStream = inStream;
     return NS_OK;
 }
 
@@ -426,7 +418,7 @@ nsDiskCacheStreamIO::GetOutputStream(PRU
     mOutStream = new nsDiskCacheOutputStream(this);
     if (!mOutStream)  return NS_ERROR_OUT_OF_MEMORY;
     
-    NS_ADDREF(*outputStream = mOutStream);
+    *outputStream = mOutStream;
     return NS_OK;
 }
 
diff --git a/netwerk/cache/src/nsDiskCacheStreams.h b/netwerk/cache/src/nsDiskCacheStreams.h
--- a/netwerk/cache/src/nsDiskCacheStreams.h
+++ b/netwerk/cache/src/nsDiskCacheStreams.h
@@ -55,7 +55,7 @@ class nsDiskCacheOutputStream;
 class nsDiskCacheOutputStream;
 class nsDiskCacheDevice;
 
-class nsDiskCacheStreamIO : public nsISupports {
+class nsDiskCacheStreamIO : public XPCOMGCFinalizedObject, public nsISupports {
 public:
              nsDiskCacheStreamIO(nsDiskCacheBinding *   binding);
     virtual ~nsDiskCacheStreamIO();
@@ -84,9 +84,7 @@ public:
                     NS_ASSERTION(mInStreamCount >= 0, "mInStreamCount has gone negative");
                 }
 
-    // GCC 2.95.2 requires this to be defined, although we never call it.
-    // and OS/2 requires that it not be private
-    nsDiskCacheStreamIO() { NS_NOTREACHED("oops"); }
+    nsresult    Flush();
 private:
 
 
@@ -96,7 +94,6 @@ private:
     nsresult    FlushBufferToFile();
     void        UpdateFileSize();
     void        DeleteBuffer();
-    nsresult    Flush();
 
 
     nsDiskCacheBinding *        mBinding;       // not an owning reference
diff --git a/netwerk/dns/src/nsDNSService2.cpp b/netwerk/dns/src/nsDNSService2.cpp
--- a/netwerk/dns/src/nsDNSService2.cpp
+++ b/netwerk/dns/src/nsDNSService2.cpp
@@ -64,7 +64,7 @@ static const char kPrefDisableIPv6[]    
 
 //-----------------------------------------------------------------------------
 
-class nsDNSRecord : public nsIDNSRecord
+class nsDNSRecord : public XPCOMGCFinalizedObject, public nsIDNSRecord
 {
 public:
     NS_DECL_ISUPPORTS
@@ -195,8 +195,9 @@ nsDNSRecord::Rewind()
 
 //-----------------------------------------------------------------------------
 
-class nsDNSAsyncRequest : public nsResolveHostCallback
+class nsDNSAsyncRequest : public XPCOMGCFinalizedObject
                         , public nsICancelable
+                        , public nsResolveHostCallback
 {
 public:
     NS_DECL_ISUPPORTS
@@ -231,7 +232,7 @@ nsDNSAsyncRequest::OnLookupComplete(nsHo
     // need to have an owning ref when we issue the callback to enable
     // the caller to be able to addref/release multiple times without
     // destroying the record prematurely.
-    nsCOMPtr<nsIDNSRecord> rec;
+    nsIDNSRecord* rec = nsnull;
     if (NS_SUCCEEDED(status)) {
         NS_ASSERTION(hostRecord, "no host record");
         rec = new nsDNSRecord(hostRecord);
@@ -323,7 +324,7 @@ nsDNSService::Init()
     nsAdoptingCString ipv4OnlyDomains;
 
     // read prefs
-    nsCOMPtr<nsIPrefBranch2> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
+    nsIPrefBranch2* prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
     if (prefs) {
         PRInt32 val;
         if (NS_SUCCEEDED(prefs->GetIntPref(kPrefDnsCacheEntries, &val)))
@@ -354,14 +355,14 @@ nsDNSService::Init()
 
     // we have to null out mIDN since we might be getting re-initialized
     // as a result of a pref change.
-    nsCOMPtr<nsIIDNService> idn;
+    nsIIDNService* idn = nsnull;
     if (enableIDN)
         idn = do_GetService(NS_IDNSERVICE_CONTRACTID);
 
-    nsRefPtr<nsHostResolver> res;
+    nsHostResolver* res = nsnull;
     nsresult rv = nsHostResolver::Create(maxCacheEntries,
                                          maxCacheLifetime,
-                                         getter_AddRefs(res));
+                                         &res);
     if (NS_SUCCEEDED(rv)) {
         // now, set all of our member variables while holding the lock
         nsAutoLock lock(mLock);
@@ -377,7 +378,7 @@ NS_IMETHODIMP
 NS_IMETHODIMP
 nsDNSService::Shutdown()
 {
-    nsRefPtr<nsHostResolver> res;
+    nsHostResolver* res = nsnull;
     {
         nsAutoLock lock(mLock);
         res = mResolver;
@@ -397,8 +398,8 @@ nsDNSService::AsyncResolve(const nsACStr
 {
     // grab reference to global host resolver and IDN service.  beware
     // simultaneous shutdown!!
-    nsRefPtr<nsHostResolver> res;
-    nsCOMPtr<nsIIDNService> idn;
+    nsHostResolver* res = nsnull;
+    nsIIDNService* idn = nsnull;
     {
         nsAutoLock lock(mLock);
         res = mResolver;
@@ -415,13 +416,13 @@ nsDNSService::AsyncResolve(const nsACStr
             hostPtr = &hostACE;
     }
 
-    nsCOMPtr<nsIDNSListener> listenerProxy;
+    nsIDNSListener* listenerProxy = nsnull;
     if (target) {
         rv = NS_GetProxyForObject(target,
                                   NS_GET_IID(nsIDNSListener),
                                   listener,
                                   NS_PROXY_ASYNC | NS_PROXY_ALWAYS,
-                                  getter_AddRefs(listenerProxy));
+                                  (void**)&listenerProxy);
         if (NS_FAILED(rv)) return rv;
         listener = listenerProxy;
     }
@@ -432,10 +433,9 @@ nsDNSService::AsyncResolve(const nsACStr
             new nsDNSAsyncRequest(res, *hostPtr, listener, flags, af);
     if (!req)
         return NS_ERROR_OUT_OF_MEMORY;
-    NS_ADDREF(*result = req);
+    *result = req;
 
     // addref for resolver; will be released when OnLookupComplete is called.
-    NS_ADDREF(req);
     rv = res->ResolveHost(req->mHost.get(), flags, af, req);
     if (NS_FAILED(rv)) {
         NS_RELEASE(req);
@@ -451,8 +451,8 @@ nsDNSService::Resolve(const nsACString &
 {
     // grab reference to global host resolver and IDN service.  beware
     // simultaneous shutdown!!
-    nsRefPtr<nsHostResolver> res;
-    nsCOMPtr<nsIIDNService> idn;
+    nsHostResolver* res = nsnull;
+    nsIIDNService* idn = nsnull;
     {
         nsAutoLock lock(mLock);
         res = mResolver;
@@ -476,36 +476,36 @@ nsDNSService::Resolve(const nsACString &
     // on the same thread.  so, our mutex needs to be re-entrant.  in other words,
     // we need to use a monitor! ;-)
     //
-    
-    PRMonitor *mon = PR_NewMonitor();
+
+    PRMonitor *mon = nsAutoMonitor::NewMonitor("nsDNSMonitor");
     if (!mon)
         return NS_ERROR_OUT_OF_MEMORY;
 
-    PR_EnterMonitor(mon);
-    nsDNSSyncRequest syncReq(mon);
+    {
+        nsAutoMonitor automon(mon);
+        nsDNSSyncRequest syncReq(mon);
 
-    PRUint16 af = GetAFForLookup(*hostPtr);
+        PRUint16 af = GetAFForLookup(*hostPtr);
 
-    rv = res->ResolveHost(PromiseFlatCString(*hostPtr).get(), flags, af, &syncReq);
-    if (NS_SUCCEEDED(rv)) {
-        // wait for result
-        while (!syncReq.mDone)
-            PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
+        rv = res->ResolveHost(PromiseFlatCString(*hostPtr).get(), flags, af, &syncReq);
+        if (NS_SUCCEEDED(rv)) {
+            // wait for result
+            while (!syncReq.mDone)
+                automon.Wait(PR_INTERVAL_NO_TIMEOUT);
 
-        if (NS_FAILED(syncReq.mStatus))
-            rv = syncReq.mStatus;
-        else {
-            NS_ASSERTION(syncReq.mHostRecord, "no host record");
-            nsDNSRecord *rec = new nsDNSRecord(syncReq.mHostRecord);
-            if (!rec)
-                rv = NS_ERROR_OUT_OF_MEMORY;
-            else
-                NS_ADDREF(*result = rec);
+            if (NS_FAILED(syncReq.mStatus))
+                rv = syncReq.mStatus;
+            else {
+                NS_ASSERTION(syncReq.mHostRecord, "no host record");
+                nsDNSRecord *rec = new nsDNSRecord(syncReq.mHostRecord);
+                if (!rec)
+                    rv = NS_ERROR_OUT_OF_MEMORY;
+                else
+                    *result = rec;
+            }
         }
     }
-
-    PR_ExitMonitor(mon);
-    PR_DestroyMonitor(mon);
+    nsAutoMonitor::DestroyMonitor(mon);
     return rv;
 }
 
diff --git a/netwerk/dns/src/nsHostResolver.cpp b/netwerk/dns/src/nsHostResolver.cpp
--- a/netwerk/dns/src/nsHostResolver.cpp
+++ b/netwerk/dns/src/nsHostResolver.cpp
@@ -164,9 +164,8 @@ nsHostRecord::Create(const nsHostKey *ke
         return NS_ERROR_OUT_OF_MEMORY;
 
     size_t hostLen = strlen(key->host) + 1;
-    size_t size = hostLen + sizeof(nsHostRecord);
 
-    nsHostRecord *rec = (nsHostRecord*) MMgc::GCFinalizedObject::operator new(size, NS_GetGC());
+    nsHostRecord *rec = new(hostLen) nsHostRecord();
     if (!rec) {
         PR_DestroyLock(lock);
         return NS_ERROR_OUT_OF_MEMORY;
@@ -419,7 +418,7 @@ nsHostResolver::ResolveHost(const char  
 
     // if result is set inside the lock, then we need to issue the
     // callback before returning.
-    nsRefPtr<nsHostRecord> result;
+    nsHostRecord* result = nsnull;
     nsresult status = NS_OK, rv = NS_OK;
     {
         nsAutoLock lock(mLock);
@@ -499,7 +498,7 @@ nsHostResolver::DetachCallback(const cha
                                nsResolveHostCallback *callback,
                                nsresult               status)
 {
-    nsRefPtr<nsHostRecord> rec;
+    nsHostRecord* rec = nsnull;
     {
         nsAutoLock lock(mLock);
 
@@ -548,7 +547,6 @@ nsHostResolver::IssueLookup(nsHostRecord
     }
     else if (mThreadCount < MAX_THREADS) {
         // dispatch new worker thread
-        NS_ADDREF_THIS(); // owning reference passed to thread
         mThreadCount++;
         PRThread *thr = PR_CreateThread(PR_SYSTEM_THREAD,
                                         ThreadFunc,
@@ -639,7 +637,6 @@ nsHostResolver::OnLookupComplete(nsHostR
         if (rec->addr_info && !mShutdown) {
             // add to mEvictionQ
             PR_APPEND_LINK(rec, &mEvictionQ);
-            NS_ADDREF(rec);
             if (mEvictionQSize < mMaxCacheEntries)
                 mEvictionQSize++;
             else {
@@ -696,7 +693,10 @@ nsHostResolver::ThreadFunc(void *arg)
 
         // convert error code to nsresult.
         nsresult status = ai ? NS_OK : NS_ERROR_UNKNOWN_HOST;
+        NS_BeginRequest();
         resolver->OnLookupComplete(rec, status, ai);
+        NS_EndRequest();
+
         LOG(("lookup complete for %s ...\n", rec->host));
     }
     NS_RELEASE(resolver);
@@ -719,7 +719,6 @@ nsHostResolver::Create(PRUint32         
                                              maxCacheLifetime);
     if (!res)
         return NS_ERROR_OUT_OF_MEMORY;
-    NS_ADDREF(res);
 
     nsresult rv = res->Init();
     if (NS_FAILED(rv))
diff --git a/netwerk/dns/src/nsHostResolver.h b/netwerk/dns/src/nsHostResolver.h
--- a/netwerk/dns/src/nsHostResolver.h
+++ b/netwerk/dns/src/nsHostResolver.h
@@ -63,13 +63,21 @@ struct nsHostKey
 /**
  * nsHostRecord - ref counted object type stored in host resolver cache.
  */
-class nsHostRecord : public XPCOMGCFinalizedObject, public PRCList, public nsHostKey
+class nsHostRecord : public XPCOMGCFinalizedObject
+                   , public MMgc::GCFinalizable
+                   , public PRCList
+                   , public nsHostKey
 {
 public:
     NS_DECL_REFCOUNTED_THREADSAFE(nsHostRecord)
 
     /* instantiates a new host record */
     static nsresult Create(const nsHostKey *key, nsHostRecord **record);
+
+    static void* operator new(size_t size, size_t extra)
+    {
+      return MMgc::GCFinalizedObject::operator new(size + extra, NS_GetGC());
+    }
 
     /* a fully resolved host record has either a non-null |addr_info| or |addr|
      * field.  if |addr_info| is null, it implies that the |host| is an IP
diff --git a/netwerk/protocol/http/src/nsHttpAuthCache.cpp b/netwerk/protocol/http/src/nsHttpAuthCache.cpp
--- a/netwerk/protocol/http/src/nsHttpAuthCache.cpp
+++ b/netwerk/protocol/http/src/nsHttpAuthCache.cpp
@@ -79,8 +79,6 @@ nsHttpAuthCache::nsHttpAuthCache()
 
 nsHttpAuthCache::~nsHttpAuthCache()
 {
-    if (mDB)
-        ClearAll();
 }
 
 nsresult
@@ -225,19 +223,20 @@ void *
 void *
 nsHttpAuthCache::AllocTable(void *self, PRSize size)
 {
-    return malloc(size);
+    return NS_GetGC()->Alloc(size, MMgc::GC::kContainsPointers);
 }
 
 void
 nsHttpAuthCache::FreeTable(void *self, void *item)
 {
-    free(item);
+    // do nothing!
 }
 
 PLHashEntry *
 nsHttpAuthCache::AllocEntry(void *self, const void *key)
 {
-    return (PLHashEntry *) malloc(sizeof(PLHashEntry));
+    return static_cast<PLHashEntry*>
+        (NS_GetGC()->Alloc(sizeof(PLHashEntry), MMgc::GC::kContainsPointers));
 }
 
 void
@@ -250,14 +249,11 @@ nsHttpAuthCache::FreeEntry(void *self, P
         NS_NOTREACHED("should never happen");
     }
     else if (flag == HT_FREE_ENTRY) {
-        // three wonderful flavors of freeing memory ;-)
-        delete (nsHttpAuthNode *) he->value;
         nsCRT::free((char *) he->key);
-        free(he);
     }
 }
 
-PLHashAllocOps nsHttpAuthCache::gHashAllocOps =
+const PLHashAllocOps nsHttpAuthCache::gHashAllocOps =
 {
     nsHttpAuthCache::AllocTable,
     nsHttpAuthCache::FreeTable,
@@ -444,21 +440,6 @@ nsHttpAuthEntry::Set(const char *path,
 // nsHttpAuthNode
 //-----------------------------------------------------------------------------
 
-nsHttpAuthNode::nsHttpAuthNode()
-{
-    LOG(("Creating nsHttpAuthNode @%x\n", this));
-}
-
-nsHttpAuthNode::~nsHttpAuthNode()
-{
-    LOG(("Destroying nsHttpAuthNode @%x\n", this));
-
-    PRInt32 i;
-    for (i=0; i<mList.Count(); ++i)
-        delete (nsHttpAuthEntry *) mList[i];
-    mList.Clear();
-}
-
 nsHttpAuthEntry *
 nsHttpAuthNode::LookupEntryByPath(const char *path)
 {
@@ -540,6 +521,5 @@ nsHttpAuthNode::ClearAuthEntry(const cha
     nsHttpAuthEntry *entry = LookupEntryByRealm(realm);
     if (entry) {
         mList.RemoveElement(entry); // double search OK
-        delete entry;
     }
 }
diff --git a/netwerk/protocol/http/src/nsHttpAuthCache.h b/netwerk/protocol/http/src/nsHttpAuthCache.h
--- a/netwerk/protocol/http/src/nsHttpAuthCache.h
+++ b/netwerk/protocol/http/src/nsHttpAuthCache.h
@@ -104,7 +104,7 @@ private:
 // nsHttpAuthEntry
 //-----------------------------------------------------------------------------
 
-class nsHttpAuthEntry
+class nsHttpAuthEntry : public XPCOMGCFinalizedObject, public MMgc::GCFinalizable
 {
 public:
     const char *Realm()       const { return mRealm; }
@@ -161,11 +161,10 @@ private:
 // nsHttpAuthNode
 //-----------------------------------------------------------------------------
 
-class nsHttpAuthNode
+class nsHttpAuthNode : public XPCOMGCObject
 {
 private:
-    nsHttpAuthNode();
-   ~nsHttpAuthNode();
+    nsHttpAuthNode() { }
 
     // path can be null, in which case we'll search for an entry
     // with a null path.
@@ -187,7 +186,7 @@ private:
     PRUint32 EntryCount() { return (PRUint32) mList.Count(); }
 
 private:
-    nsVoidArray mList; // list of nsHttpAuthEntry objects
+    nsVoidArrayBase<GCAllocator> mList; // list of nsHttpAuthEntry objects
 
     friend class nsHttpAuthCache;
 };
@@ -258,7 +257,7 @@ private:
     static PLHashEntry* PR_CALLBACK AllocEntry(void *, const void *key);
     static void         PR_CALLBACK FreeEntry(void *, PLHashEntry *he, PRUintn flag);
 
-    static PLHashAllocOps gHashAllocOps;
+    static const PLHashAllocOps gHashAllocOps;
     
 private:
     PLHashTable *mDB; // "host:port" --> nsHttpAuthNode
diff --git a/netwerk/protocol/http/src/nsHttpConnection.h b/netwerk/protocol/http/src/nsHttpConnection.h
--- a/netwerk/protocol/http/src/nsHttpConnection.h
+++ b/netwerk/protocol/http/src/nsHttpConnection.h
@@ -60,9 +60,10 @@
 // accessed from any other thread.
 //-----------------------------------------------------------------------------
 
-class nsHttpConnection : public nsAHttpSegmentReader
+class nsHttpConnection : public XPCOMGCFinalizedObject
+                       , public nsIInputStreamCallback
+                       , public nsAHttpSegmentReader
                        , public nsAHttpSegmentWriter
-                       , public nsIInputStreamCallback
                        , public nsIOutputStreamCallback
                        , public nsITransportEventSink
                        , public nsIInterfaceRequestor
diff --git a/netwerk/protocol/http/src/nsHttpConnectionInfo.h b/netwerk/protocol/http/src/nsHttpConnectionInfo.h
--- a/netwerk/protocol/http/src/nsHttpConnectionInfo.h
+++ b/netwerk/protocol/http/src/nsHttpConnectionInfo.h
@@ -51,44 +51,20 @@
 // nsHttpConnectionInfo - holds the properties of a connection
 //-----------------------------------------------------------------------------
 
-class nsHttpConnectionInfo
+class nsHttpConnectionInfo : public XPCOMGCObject
 {
 public:
     nsHttpConnectionInfo(const nsACString &host, PRInt32 port,
                          nsProxyInfo* proxyInfo,
                          PRBool usingSSL=PR_FALSE)
-        : mRef(0)
-        , mProxyInfo(proxyInfo)
+        : mProxyInfo(proxyInfo)
         , mUsingSSL(usingSSL) 
     {
-        LOG(("Creating nsHttpConnectionInfo @%x\n", this));
-
         mUsingHttpProxy = (proxyInfo && !nsCRT::strcmp(proxyInfo->Type(), "http"));
 
         SetOriginServer(host, port);
     }
     
-   ~nsHttpConnectionInfo()
-    {
-        LOG(("Destroying nsHttpConnectionInfo @%x\n", this));
-    }
-
-    nsrefcnt AddRef()
-    {
-        nsrefcnt n = PR_AtomicIncrement((PRInt32 *) &mRef);
-        NS_LOG_ADDREF(this, n, "nsHttpConnectionInfo", sizeof(*this));
-        return n;
-    }
-
-    nsrefcnt Release()
-    {
-        nsrefcnt n = PR_AtomicDecrement((PRInt32 *) &mRef);
-        NS_LOG_RELEASE(this, n, "nsHttpConnectionInfo");
-        if (n == 0)
-            delete this;
-        return n;
-    }
-
     const nsAFlatCString &HashKey() const { return mHashKey; }
 
     void SetOriginServer(const nsACString &host, PRInt32 port);
@@ -122,7 +98,11 @@ public:
     PRInt32       DefaultPort() const    { return mUsingSSL ? NS_HTTPS_DEFAULT_PORT : NS_HTTP_DEFAULT_PORT; }
             
 private:
-    nsrefcnt               mRef;
+   ~nsHttpConnectionInfo()
+    {
+        NS_NOTREACHED("Don't destruct me");
+    }
+
     nsCString              mHashKey;
     nsCString              mHost;
     PRInt32                mPort;
diff --git a/netwerk/protocol/http/src/nsHttpConnectionMgr.h b/netwerk/protocol/http/src/nsHttpConnectionMgr.h
--- a/netwerk/protocol/http/src/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/src/nsHttpConnectionMgr.h
@@ -86,16 +86,6 @@ public:
     //-------------------------------------------------------------------------
     // NOTE: functions below may be called on any thread.
     //-------------------------------------------------------------------------
-
-    void AddRef()
-    {
-	NS_WARNING("Don't call me");
-    }
-
-    void Release()
-    {
-	NS_WARNING("Don't call me");
-    }
 
     // adds a transaction to the list of managed transactions.
     nsresult AddTransaction(nsHttpTransaction *, PRInt32 priority);
diff --git a/netwerk/protocol/http/src/nsHttpHandler.cpp b/netwerk/protocol/http/src/nsHttpHandler.cpp
--- a/netwerk/protocol/http/src/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/src/nsHttpHandler.cpp
@@ -193,12 +193,6 @@ nsHttpHandler::~nsHttpHandler()
     // it is taken care of in xpcom shutdown event in the Observe method.
 
     LOG(("Deleting nsHttpHandler [this=%x]\n", this));
-
-    // make sure the connection manager is shutdown
-    if (mConnMgr) {
-        mConnMgr->Shutdown();
-        NS_RELEASE(mConnMgr);
-    }
 
     nsHttp::DestroyAtomTable();
 
diff --git a/netwerk/test/httpserver/Makefile.in b/netwerk/test/httpserver/Makefile.in
--- a/netwerk/test/httpserver/Makefile.in
+++ b/netwerk/test/httpserver/Makefile.in
@@ -43,7 +43,7 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE          = test_necko
+MODULE          = test_necko_httpserver
 
 EXTRA_COMPONENTS = \
                    httpd.js \
diff --git a/netwerk/test/unit/test_authentication.js b/netwerk/test/unit/test_authentication.js
--- a/netwerk/test/unit/test_authentication.js
+++ b/netwerk/test/unit/test_authentication.js
@@ -276,6 +276,8 @@ function run_test() {
 }
 
 function test_noauth() {
+  print('test_noauth\n');
+
   var chan = makeChan("http://localhost:4444/auth");
 
   listener.expectedCode = 401; // Unauthorized
@@ -285,6 +287,8 @@ function test_noauth() {
 }
 
 function test_returnfalse1() {
+  print('test_returnfalse1\n');
+
   var chan = makeChan("http://localhost:4444/auth");
 
   chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE, 1);
@@ -295,6 +299,8 @@ function test_returnfalse1() {
 }
 
 function test_wrongpw1() {
+  print('test_wrongpw1\n');
+
   var chan = makeChan("http://localhost:4444/auth");
 
   chan.notificationCallbacks = new Requestor(FLAG_WRONG_PASSWORD, 1);
@@ -305,6 +311,8 @@ function test_wrongpw1() {
 }
 
 function test_prompt1() {
+  print('test_prompt1\n');
+
   var chan = makeChan("http://localhost:4444/auth");
 
   chan.notificationCallbacks = new Requestor(0, 1);
@@ -315,6 +323,8 @@ function test_prompt1() {
 }
 
 function test_returnfalse2() {
+  print('test_returnfalse2\n');
+
   var chan = makeChan("http://localhost:4444/auth");
 
   chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE, 2);
@@ -325,6 +335,8 @@ function test_returnfalse2() {
 }
 
 function test_wrongpw2() {
+  print('test_wrongpw2\n');
+
   var chan = makeChan("http://localhost:4444/auth");
 
   chan.notificationCallbacks = new Requestor(FLAG_WRONG_PASSWORD, 2);
@@ -335,6 +347,8 @@ function test_wrongpw2() {
 }
 
 function test_prompt2() {
+  print('test_prompt2\n');
+
   var chan = makeChan("http://localhost:4444/auth");
 
   chan.notificationCallbacks = new Requestor(0, 2);
@@ -345,6 +359,8 @@ function test_prompt2() {
 }
 
 function test_ntlm() {
+  print('test_ntlm\n');
+
   var chan = makeChan("http://localhost:4444/auth/ntlm/simple");
 
   chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE, 2);
@@ -355,6 +371,8 @@ function test_ntlm() {
 }
 
 function test_auth() {
+  print('test_auth\n');
+
   var chan = makeChan("http://localhost:4444/auth/realm");
 
   chan.notificationCallbacks = new RealmTestRequestor();
@@ -365,6 +383,8 @@ function test_auth() {
 }
 
 function test_digest_noauth() {
+  print('test_digest_noauth\n');
+
   var chan = makeChan("http://localhost:4444/auth/digest");
 
   //chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE, 2);
@@ -375,6 +395,8 @@ function test_digest_noauth() {
 }
 
 function test_digest() {
+  print('test_digest\n');
+
   var chan = makeChan("http://localhost:4444/auth/digest");
 
   chan.notificationCallbacks = new Requestor(0, 2);
@@ -385,6 +407,8 @@ function test_digest() {
 }
 
 function test_digest_bogus_user() {
+  print('test_digest_bogus_user\n');
+
   var chan = makeChan("http://localhost:4444/auth/digest");
   chan.notificationCallbacks =  new Requestor(0, 2, "foo\nbar");
   listener.expectedCode = 401; // unauthorized