Bug 474369 - get rid of nsVoidArray, xpcom part; r=bsmedberg
authorArpad Borsos <arpad.borsos@googlemail.com>
Fri, 03 Apr 2009 18:43:08 +0200
changeset 26914 cd38a0fbe1ebde36eea34ce011687f75a023f7bb
parent 26913 f2f8545e079b7e49084c9bce4f28635c786a1f25
child 26915 fec668a5871423cb6c52f15adf5ddd9d9152a742
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs474369
milestone1.9.2a1pre
Bug 474369 - get rid of nsVoidArray, xpcom part; r=bsmedberg
xpcom/base/nsExceptionService.h
xpcom/base/nsTraceRefcntImpl.cpp
xpcom/components/nsComponentManager.cpp
xpcom/components/nsNativeComponentLoader.h
xpcom/ds/nsHashPropertyBag.h
xpcom/io/nsFastLoadFile.h
xpcom/io/nsLocalFileOSX.mm
xpcom/tests/TestVoidBTree.cpp
xpcom/threads/TimerThread.cpp
xpcom/threads/TimerThread.h
xpcom/threads/nsTimerImpl.cpp
--- a/xpcom/base/nsExceptionService.h
+++ b/xpcom/base/nsExceptionService.h
@@ -34,17 +34,16 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsExceptionService_h__
 #define nsExceptionService_h__
 
-#include "nsVoidArray.h"
 #include "nsIException.h"
 #include "nsIExceptionService.h"
 #include "nsIObserverService.h"
 #include "nsHashtable.h"
 #include "nsIObserver.h"
 
 class nsExceptionManager;
 
--- a/xpcom/base/nsTraceRefcntImpl.cpp
+++ b/xpcom/base/nsTraceRefcntImpl.cpp
@@ -34,17 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsTraceRefcntImpl.h"
 #include "nscore.h"
 #include "nsISupports.h"
-#include "nsVoidArray.h"
+#include "nsTArray.h"
 #include "prprf.h"
 #include "prlog.h"
 #include "plstr.h"
 #include "prlink.h"
 #include <stdlib.h>
 #include "nsCOMPtr.h"
 #include "nsCRT.h"
 #include <math.h>
@@ -273,17 +273,17 @@ public:
     mNewStats.mObjsOutstandingTotal += cnt;
     mNewStats.mObjsOutstandingSquared += cnt * cnt;
   }
 
   static PRIntn DumpEntry(PLHashEntry *he, PRIntn i, void *arg) {
     BloatEntry* entry = (BloatEntry*)he->value;
     if (entry) {
       entry->Accumulate();
-      static_cast<nsVoidArray*>(arg)->AppendElement(entry);
+      static_cast<nsTArray<BloatEntry*>*>(arg)->AppendElement(entry);
     }
     return HT_ENUMERATE_NEXT;
   }
 
   static PRIntn TotalEntries(PLHashEntry *he, PRIntn i, void *arg) {
     BloatEntry* entry = (BloatEntry*)he->value;
     if (entry && nsCRT::strcmp(entry->mClassName, "TOTAL") != 0) {
       entry->Total((BloatEntry*)arg);
@@ -451,16 +451,27 @@ static PRIntn DumpSerialNumbers(PLHashEn
                             record->serialNumber,
                             NS_INT32_TO_PTR(aHashEntry->key),
                             record->refCount);
 #endif
   return HT_ENUMERATE_NEXT;
 }
 
 
+NS_SPECIALIZE_TEMPLATE
+class nsDefaultComparator <BloatEntry*, BloatEntry*> {
+  public:
+    PRBool Equals(BloatEntry* const& aA, BloatEntry* const& aB) const {
+      return PL_strcmp(aA->GetClassName(), aB->GetClassName()) == 0;
+    }
+    PRBool LessThan(BloatEntry* const& aA, BloatEntry* const& aB) const {
+      return PL_strcmp(aA->GetClassName(), aB->GetClassName()) < 0;
+    }
+};
+
 #endif /* NS_IMPL_REFCNT_LOGGING */
 
 NS_COM nsresult
 nsTraceRefcntImpl::DumpStatistics(StatisticsType type, FILE* out)
 {
 #ifdef NS_IMPL_REFCNT_LOGGING
   if (gBloatLog == nsnull || gBloatView == nsnull) {
     return NS_ERROR_FAILURE;
@@ -486,38 +497,26 @@ nsTraceRefcntImpl::DumpStatistics(Statis
   else {
     if (gLogLeaksOnly)
       msg = "ALL (cumulative) LEAK STATISTICS";
     else
       msg = "ALL (cumulative) LEAK AND BLOAT STATISTICS";
   }
   const PRBool leaked = total.PrintDumpHeader(out, msg, type);
 
-  nsVoidArray entries;
+  nsTArray<BloatEntry*> entries;
   PL_HashTableEnumerateEntries(gBloatView, BloatEntry::DumpEntry, &entries);
-  const PRInt32 count = entries.Count();
+  const PRUint32 count = entries.Length();
 
   if (!gLogLeaksOnly || leaked) {
     // Sort the entries alphabetically by classname.
-    PRInt32 i, j;
-    for (i = count - 1; i >= 1; --i) {
-      for (j = i - 1; j >= 0; --j) {
-        BloatEntry* left  = static_cast<BloatEntry*>(entries[i]);
-        BloatEntry* right = static_cast<BloatEntry*>(entries[j]);
+    entries.Sort();
 
-        if (PL_strcmp(left->GetClassName(), right->GetClassName()) < 0) {
-          entries.ReplaceElementAt(right, i);
-          entries.ReplaceElementAt(left, j);
-        }
-      }
-    }
-
-    // Enumerate from back-to-front, so things come out in alpha order
-    for (i = 0; i < count; ++i) {
-      BloatEntry* entry = static_cast<BloatEntry*>(entries[i]);
+    for (PRUint32 i = 0; i < count; ++i) {
+      BloatEntry* entry = entries[i];
       entry->Dump(i, out, type);
     }
 
     fprintf(out, "\n");
   }
 
   fprintf(out, "nsTraceRefcntImpl::DumpStatistics: %d entries\n", count);
 
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -80,16 +80,17 @@
 #include "nsReadableUtils.h"
 #include "nsString.h"
 #include "nsXPIDLString.h"
 #include "prcmon.h"
 #include "xptinfo.h" // this after nsISupports, to pick up IID so that xpt stuff doesn't try to define it itself...
 #include "nsThreadUtils.h"
 #include "prthread.h"
 #include "private/pprthred.h"
+#include "nsTArray.h"
 
 #include "nsInt64.h"
 #include "nsManifestLineReader.h"
 
 #include NEW_H     // for placement new
 
 
 #ifdef XP_BEOS
@@ -324,19 +325,19 @@ public:
                                void *converterData);
     PRInt32 Count() { return mCount; }
 private:
     PLDHashTableEnumeratorImpl(); /* no implementation */
 
     ~PLDHashTableEnumeratorImpl();
     void ReleaseElements();
 
-    nsVoidArray   mElements;
-    PRInt32       mCount, mCurrent;
-    PRMonitor*    mMonitor;
+    nsTArray<nsISupports*> mElements;
+    PRInt32                mCount, mCurrent;
+    PRMonitor*             mMonitor;
 
     struct Closure {
         PRBool                        succeeded;
         EnumeratorConverter           converter;
         void                          *data;
         PLDHashTableEnumeratorImpl    *impl;
     };
 
@@ -396,19 +397,17 @@ PLDHashTableEnumeratorImpl::~PLDHashTabl
     if (mMonitor)
         nsAutoMonitor::DestroyMonitor(mMonitor);
 }
 
 void
 PLDHashTableEnumeratorImpl::ReleaseElements()
 {
     for (PRInt32 i = 0; i < mCount; i++) {
-        nsISupports *supports = reinterpret_cast<nsISupports *>
-                                                (mElements[i]);
-        NS_IF_RELEASE(supports);
+        NS_IF_RELEASE(mElements[i]);
     }
 }
 
 NS_IMETHODIMP
 PL_NewDHashTableEnumerator(PLDHashTable *table,
                            EnumeratorConverter converter,
                            void *converterData,
                            PLDHashTableEnumeratorImpl **retval)
@@ -471,17 +470,17 @@ PLDHashTableEnumeratorImpl::Next()
 }
 
 NS_IMETHODIMP
 PLDHashTableEnumeratorImpl::CurrentItem(nsISupports **retval)
 {
     if (!mCount || mCurrent == mCount)
         return NS_ERROR_FAILURE;
 
-    *retval = reinterpret_cast<nsISupports *>(mElements[mCurrent]);
+    *retval = mElements[mCurrent];
     if (*retval)
         NS_ADDREF(*retval);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 PLDHashTableEnumeratorImpl::IsDone()
--- a/xpcom/components/nsNativeComponentLoader.h
+++ b/xpcom/components/nsNativeComponentLoader.h
@@ -35,17 +35,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsNativeModuleLoader_h__
 #define nsNativeModuleLoader_h__
 
 #include "nsISupports.h"
 #include "nsIModuleLoader.h"
-#include "nsVoidArray.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsIModule.h"
 #include "prlink.h"
 
 class nsNativeModuleLoader : public nsIModuleLoader
 {
  public:
--- a/xpcom/ds/nsHashPropertyBag.h
+++ b/xpcom/ds/nsHashPropertyBag.h
@@ -37,17 +37,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsHashPropertyBag_h___
 #define nsHashPropertyBag_h___
 
 #include "nsCOMPtr.h"
 #include "nsCOMArray.h"
-#include "nsVoidArray.h"
 
 #include "nsIVariant.h"
 #include "nsIWritablePropertyBag.h"
 #include "nsIWritablePropertyBag2.h"
 #include "nsInterfaceHashtable.h"
 
 // Set IMETHOD_VISIBILITY to empty so that the class-level NS_COM declaration
 // controls member method visibility.
--- a/xpcom/io/nsFastLoadFile.h
+++ b/xpcom/io/nsFastLoadFile.h
@@ -46,17 +46,16 @@
 #include "prtypes.h"
 #include "pldhash.h"
 
 #include "nsBinaryStream.h"
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
 #include "nsID.h"
 #include "nsMemory.h"
-#include "nsVoidArray.h"
 
 #include "nsIFastLoadFileControl.h"
 #include "nsIFastLoadService.h"
 #include "nsISeekableStream.h"
 #include "nsISupportsArray.h"
 
 /**
  * FastLoad file Object ID (OID) is an identifier for multiply and cyclicly
--- a/xpcom/io/nsLocalFileOSX.mm
+++ b/xpcom/io/nsLocalFileOSX.mm
@@ -45,25 +45,23 @@
 
 #include "nsObjCExceptions.h"
 #include "nsAutoPtr.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsIDirectoryEnumerator.h"
 #include "nsISimpleEnumerator.h"
 #include "nsITimelineService.h"
-#include "nsVoidArray.h"
 #include "nsTArray.h"
 
 #include "plbase64.h"
 #include "prmem.h"
 #include "nsCRT.h"
 #include "nsHashKeys.h"
 
-#include "nsTArray.h"
 #include "nsTraceRefcntImpl.h"
 
 #include <Carbon/Carbon.h>
 #import <Cocoa/Cocoa.h>
 
 #include <unistd.h>
 #include <sys/stat.h>
 #include <stdlib.h>
deleted file mode 100644
--- a/xpcom/tests/TestVoidBTree.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org Code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1999
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "nsVoidBTree.h"
-#include "nsVoidArray.h"
-
-#define COUNT 1024
-#define POINTER(i) reinterpret_cast<void*>(4 + 4 * (i))
-
-static PRBool
-Equal(const nsVoidArray& aControl, const nsVoidBTree& aTest)
-{
-    if (aControl.Count() != aTest.Count()) {
-        printf("counts not equal; ");
-        return PR_FALSE;
-    }
-
-    for (PRInt32 i = aControl.Count() - 1; i >= 0; --i) {
-        if (aControl[i] != aTest[i]) {
-            printf("element %d differs; ", i);
-            return PR_FALSE;
-        }
-    }
-
-    return PR_TRUE;
-}
-
-
-static void
-CheckForwardEnumeration(const nsVoidArray& aControl, const nsVoidBTree& aTest)
-{
-    PRInt32 index = 0;
-
-    nsVoidBTree::ConstIterator last = aTest.Last();
-    for (nsVoidBTree::ConstIterator element = aTest.First(); element != last; ++element, ++index) {
-        if (*element != aControl[index]) {
-            printf("failed forward enumeration\n");
-            exit(-1);
-        }
-    }
-
-    if (index != aControl.Count()) {
-        printf("erratic termination during forward enumeration\n");
-        exit(-1);
-    }
-}
-
-static void
-CheckBackwardEnumeration(const nsVoidArray& aControl, const nsVoidBTree& aTest)
-{
-    PRInt32 index = aControl.Count();
-    nsVoidBTree::ConstIterator first = aTest.First();
-    nsVoidBTree::ConstIterator element = aTest.Last();
-
-    if (first != element) {
-        do {
-            if (*--element != aControl[--index]) {
-                printf("failed backward enumeration\n");
-                exit(-1);
-            }
-        } while (element != first);
-    }
-
-    if (index != 0) {
-        printf("erratic termination during backward enumeration\n");
-        exit(-1);
-    }
-}
-
-int main(int argc, char* argv[])
-{
-    nsVoidBTree btree;
-
-    PRInt32 i;
-
-    //----------------------------------------
-    // Tail fill
-    for (i = 0; i < COUNT; ++i)
-        btree.InsertElementAt(reinterpret_cast<void*>(POINTER(i)), i);
-
-    for (i = 0; i < COUNT; ++i) {
-        if (btree[i] != POINTER(i)) {
-            printf("tail fill failed\n");
-            return -1;
-        }
-    }
-
-    printf("tail fill succeeded\n");
-
-    //----------------------------------------
-    // Tail empty
-    for (i = COUNT - 1; i >= 0; --i)
-        btree.RemoveElementAt(i);
-
-    if (btree.Count() != 0) {
-        printf("tail empty failed\n");
-        return -1;
-    }
-
-    printf("tail empty succeeded\n");
-
-    // N.B. no intervening Clear() to verify that we handle the re-use
-    // case.
-
-    //----------------------------------------
-    // Front fill
-    for (i = 0; i < COUNT; ++i)
-        btree.InsertElementAt(POINTER(i), 0);
-
-    for (i = 0; i < COUNT; ++i) {
-        if (btree[COUNT - (i + 1)] != POINTER(i)) {
-            printf("simple front fill failed\n");
-            return -1;
-        }
-    }
-
-    printf("front fill succeeded\n");
-
-    //----------------------------------------
-    // Front empty
-    for (i = COUNT - 1; i >= 0; --i)
-        btree.RemoveElementAt(0);
-
-    if (btree.Count() != 0) {
-        printf("front empty failed\n");
-        return -1;
-    }
-
-    printf("front empty succeeded\n");
-    fflush(stdout);
-
-    //----------------------------------------
-    // Test boundary conditions with small btree
-
-    {
-        printf("small btree boundary conditions ");
-        fflush(stdout);
-
-        nsVoidArray control;
-        btree.Clear();
-
-        CheckBackwardEnumeration(control, btree);
-        CheckForwardEnumeration(control, btree);
-
-        btree.AppendElement(POINTER(0));
-        control.AppendElement(POINTER(0));
-
-        CheckBackwardEnumeration(control, btree);
-        CheckForwardEnumeration(control, btree);
-
-        btree.AppendElement(POINTER(1));
-        control.AppendElement(POINTER(1));
-
-        CheckBackwardEnumeration(control, btree);
-        CheckForwardEnumeration(control, btree);
-
-        btree.RemoveElementAt(0);
-        btree.RemoveElementAt(0);
-        control.RemoveElementAt(0);
-        control.RemoveElementAt(0);
-
-        CheckBackwardEnumeration(control, btree);
-        CheckForwardEnumeration(control, btree);
-
-        printf("succeeded\n");
-    }
-
-    //----------------------------------------
-    // Iterator
-    {
-        nsVoidArray control;
-        btree.Clear();
-
-        // Fill
-        for (i = 0; i < COUNT; ++i) {
-            PRInt32 slot = i ? rand() % i : 0;
-
-            btree.InsertElementAt(POINTER(i), slot);
-            control.InsertElementAt(POINTER(i), slot);
-
-            if (! Equal(control, btree)) {
-                printf("failed\n");
-                return -1;
-            }
-        }
-
-        for (nsVoidBTree::Iterator m = btree.First(); m != btree.Last(); ++m) {
-            nsVoidBTree::Iterator n;
-            for (n = m, ++n; n != btree.Last(); ++n) {
-                if (*m > *n) {
-                    void* tmp = *m;
-                    *m = *n;
-                    *n = tmp;
-                }
-            }
-        }
-
-        nsVoidBTree::Iterator el;
-        for (el = btree.First(), i = 0; el != btree.Last(); ++el, ++i) {
-            if (*el != POINTER(i)) {
-                printf("bubble sort failed\n");
-                return -1;
-            }
-        }
-
-        printf("iteration succeeded\n");
-    }
-
-    //----------------------------------------
-    // Random hammering
-
-    printf("random fill/empty: ");
-
-    for (PRInt32 iter = 10; iter >= 1; --iter) {
-        printf("%d ", iter);
-        fflush(stdout);
-
-        nsVoidArray control;
-        btree.Clear();
-
-        // Fill
-        for (i = 0; i < COUNT; ++i) {
-            PRInt32 slot = i ? rand() % i : 0;
-
-            btree.InsertElementAt(POINTER(i), slot);
-            control.InsertElementAt(POINTER(i), slot);
-
-            if (! Equal(control, btree)) {
-                printf("failed\n");
-                return -1;
-            }
-        }
-
-        // IndexOf
-        for (i = 0; i < COUNT; ++i) {
-            void* element = control[i];
-            if (btree.IndexOf(element) != i) {
-                printf("failed IndexOf at %d\n", i);
-                return -1;
-            }
-        }
-
-        // Backward enumeration
-        CheckBackwardEnumeration(control, btree);
-               
-        // Forward enumeration
-        CheckForwardEnumeration(control, btree);
-
-        // Empty
-        for (i = COUNT - 1; i >= 0; --i) {
-            PRInt32 slot = i ? rand() % i : 0;
-
-            btree.RemoveElementAt(slot);
-            control.RemoveElementAt(slot);
-
-            if (! Equal(control, btree)) {
-                printf("failed\n");
-                return -1;
-            }
-        }
-    }
-
-    printf("succeeded\n");
-
-    return 0;
-}
--- a/xpcom/threads/TimerThread.cpp
+++ b/xpcom/threads/TimerThread.cpp
@@ -69,17 +69,17 @@ TimerThread::~TimerThread()
 {
   if (mCondVar)
     PR_DestroyCondVar(mCondVar);
   if (mLock)
     PR_DestroyLock(mLock);
 
   mThread = nsnull;
 
-  NS_ASSERTION(mTimers.Count() == 0, "Timers remain in TimerThread::~TimerThread");
+  NS_ASSERTION(mTimers.IsEmpty(), "Timers remain in TimerThread::~TimerThread");
 }
 
 nsresult
 TimerThread::InitLocks()
 {
   NS_ASSERTION(!mLock, "InitLocks called twice?");
   mLock = PR_NewLock();
   if (!mLock)
@@ -149,40 +149,39 @@ nsresult TimerThread::Init()
 
 nsresult TimerThread::Shutdown()
 {
   PR_LOG(gTimerLog, PR_LOG_DEBUG, ("TimerThread::Shutdown begin\n"));
 
   if (!mThread)
     return NS_ERROR_NOT_INITIALIZED;
 
-  nsVoidArray timers;
+  nsTArray<nsTimerImpl*> timers;
   {   // lock scope
     nsAutoLock lock(mLock);
 
     mShutdown = PR_TRUE;
 
     // notify the cond var so that Run() can return
     if (mCondVar && mWaiting)
       PR_NotifyCondVar(mCondVar);
 
     // Need to copy content of mTimers array to a local array
     // because call to timers' ReleaseCallback() (and release its self)
     // must not be done under the lock. Destructor of a callback
     // might potentially call some code reentering the same lock
     // that leads to unexpected behavior or deadlock.
     // See bug 422472.
-    PRBool rv = timers.AppendElements(mTimers);
-    NS_ASSERTION(rv, "Could not copy timers array, remaining timers will not be released");
+    timers.AppendElements(mTimers);
     mTimers.Clear();
   }
 
-  PRInt32 timersCount = timers.Count();
-  for (PRInt32 i = 0; i < timersCount; i++) {
-    nsTimerImpl *timer = static_cast<nsTimerImpl*>(timers[i]);
+  PRUint32 timersCount = timers.Length();
+  for (PRUint32 i = 0; i < timersCount; i++) {
+    nsTimerImpl *timer = timers[i];
     timer->ReleaseCallback();
     ReleaseTimerInternal(timer);
   }
 
   mThread->Shutdown();    // wait for the thread to die
 
   PR_LOG(gTimerLog, PR_LOG_DEBUG, ("TimerThread::Shutdown end\n"));
   return NS_OK;
@@ -252,18 +251,18 @@ NS_IMETHODIMP TimerThread::Run()
     if (mSleeping) {
       // Sleep for 0.1 seconds while not firing timers.
       waitFor = PR_MillisecondsToInterval(100);
     } else {
       waitFor = PR_INTERVAL_NO_TIMEOUT;
       PRIntervalTime now = PR_IntervalNow();
       nsTimerImpl *timer = nsnull;
 
-      if (mTimers.Count() > 0) {
-        timer = static_cast<nsTimerImpl*>(mTimers[0]);
+      if (!mTimers.IsEmpty()) {
+        timer = mTimers[0];
 
         if (!TIMER_LESS_THAN(now, timer->mTimeout + mTimeoutAdjustment)) {
     next:
           // NB: AddRef before the Release under RemoveTimerInternal to avoid
           // mRefCnt passing through zero, in case all other refs than the one
           // from mTimers have gone away (the last non-mTimers[i]-ref's Release
           // must be racing with us, blocked in gThread->RemoveTimer waiting
           // for TimerThread::mLock, under nsTimerImpl::Release.
@@ -312,18 +311,18 @@ NS_IMETHODIMP TimerThread::Run()
             break;
 
           // Update now, as PostTimerEvent plus the locking may have taken a
           // tick or two, and we may goto next below.
           now = PR_IntervalNow();
         }
       }
 
-      if (mTimers.Count() > 0) {
-        timer = static_cast<nsTimerImpl *>(mTimers[0]);
+      if (!mTimers.IsEmpty()) {
+        timer = mTimers[0];
 
         PRIntervalTime timeout = timer->mTimeout + mTimeoutAdjustment;
 
         // Don't wait at all (even for PR_INTERVAL_NO_WAIT) if the next timer
         // is due now or overdue.
         if (!TIMER_LESS_THAN(now, timeout))
           goto next;
         waitFor = timeout - now;
@@ -407,37 +406,37 @@ nsresult TimerThread::RemoveTimer(nsTime
 
 // This function must be called from within a lock
 PRInt32 TimerThread::AddTimerInternal(nsTimerImpl *aTimer)
 {
   if (mShutdown)
     return -1;
 
   PRIntervalTime now = PR_IntervalNow();
-  PRInt32 count = mTimers.Count();
-  PRInt32 i = 0;
+  PRUint32 count = mTimers.Length();
+  PRUint32 i = 0;
   for (; i < count; i++) {
-    nsTimerImpl *timer = static_cast<nsTimerImpl *>(mTimers[i]);
+    nsTimerImpl *timer = mTimers[i];
 
     // Don't break till we have skipped any overdue timers.  Do not include
     // mTimeoutAdjustment here, because we are really trying to avoid calling
     // TIMER_LESS_THAN(t, u), where the t is now + DELAY_INTERVAL_MAX, u is
     // now - overdue, and DELAY_INTERVAL_MAX + overdue > DELAY_INTERVAL_LIMIT.
     // In other words, we want to use now-based time, now adjusted time, even
     // though "overdue" ultimately depends on adjusted time.
 
     // XXX does this hold for TYPE_REPEATING_PRECISE?  /be
 
     if (TIMER_LESS_THAN(now, timer->mTimeout) &&
         TIMER_LESS_THAN(aTimer->mTimeout, timer->mTimeout)) {
       break;
     }
   }
 
-  if (!mTimers.InsertElementAt(aTimer, i))
+  if (!mTimers.InsertElementAt(i, aTimer))
     return -1;
 
   aTimer->mArmed = PR_TRUE;
   NS_ADDREF(aTimer);
   return i;
 }
 
 PRBool TimerThread::RemoveTimerInternal(nsTimerImpl *aTimer)
@@ -459,18 +458,18 @@ void TimerThread::ReleaseTimerInternal(n
 void TimerThread::DoBeforeSleep()
 {
   mSleeping = PR_TRUE;
 }
 
 void TimerThread::DoAfterSleep()
 {
   mSleeping = PR_TRUE; // wake may be notified without preceding sleep notification
-  for (PRInt32 i = 0; i < mTimers.Count(); i ++) {
-    nsTimerImpl *timer = static_cast<nsTimerImpl*>(mTimers[i]);
+  for (PRUint32 i = 0; i < mTimers.Length(); i ++) {
+    nsTimerImpl *timer = mTimers[i];
     // get and set the delay to cause its timeout to be recomputed
     PRUint32 delay;
     timer->GetDelay(&delay);
     timer->SetDelay(delay);
   }
 
   // nuke the stored adjustments, so they get recalibrated
   mTimeoutAdjustment = 0;
--- a/xpcom/threads/TimerThread.h
+++ b/xpcom/threads/TimerThread.h
@@ -42,17 +42,17 @@
 #define TimerThread_h___
 
 #include "nsIObserver.h"
 #include "nsIRunnable.h"
 #include "nsIThread.h"
 
 #include "nsTimerImpl.h"
 
-#include "nsVoidArray.h"
+#include "nsTArray.h"
 
 #include "prcvar.h"
 #include "prinrval.h"
 #include "prlock.h"
 
 class TimerThread : public nsIRunnable,
                     public nsIObserver
 {
@@ -96,17 +96,17 @@ private:
   nsCOMPtr<nsIThread> mThread;
   PRLock *mLock;
   PRCondVar *mCondVar;
 
   PRPackedBool mShutdown;
   PRPackedBool mWaiting;
   PRPackedBool mSleeping;
   
-  nsVoidArray mTimers;
+  nsTArray<nsTimerImpl*> mTimers;
 
 #define DELAY_LINE_LENGTH_LOG2  5
 #define DELAY_LINE_LENGTH_MASK  PR_BITMASK(DELAY_LINE_LENGTH_LOG2)
 #define DELAY_LINE_LENGTH       PR_BIT(DELAY_LINE_LENGTH_LOG2)
 
   PRInt32  mDelayLine[DELAY_LINE_LENGTH];
   PRUint32 mDelayLineCounter;
   PRUint32 mMinTimerPeriod;     // milliseconds
--- a/xpcom/threads/nsTimerImpl.cpp
+++ b/xpcom/threads/nsTimerImpl.cpp
@@ -37,17 +37,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsTimerImpl.h"
 #include "TimerThread.h"
 #include "nsAutoLock.h"
 #include "nsAutoPtr.h"
-#include "nsVoidArray.h"
 #include "nsThreadManager.h"
 #include "nsThreadUtils.h"
 #include "prmem.h"
 
 static PRInt32          gGenerator = 0;
 static TimerThread*     gThread = nsnull;
 
 #ifdef DEBUG_TIMERS