Bug 715770 (part 3) - Remove nsRecyclingAllocator. r=bsmedberg.
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 17 Jan 2012 17:29:52 -0800
changeset 84765 3b8dd350dbab3c8f6322920a2a50704a2ce04a13
parent 84764 7fe6463d454786c023235a4b1da4f66d45fae4c3
child 84766 b105fa66bb3707858f9ab67cfbf40e0c41c51fbf
push id21873
push usermlamouri@mozilla.com
push dateWed, 18 Jan 2012 10:29:07 +0000
treeherdermozilla-central@7538f4d4697c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs715770
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 715770 (part 3) - Remove nsRecyclingAllocator. r=bsmedberg.
xpcom/build/XPCOM.h
xpcom/build/XPCOMModule.inc
xpcom/build/nsXPComInit.cpp
xpcom/ds/Makefile.in
xpcom/ds/nsIRecyclingAllocator.idl
xpcom/ds/nsRecyclingAllocator.cpp
xpcom/ds/nsRecyclingAllocator.h
--- a/xpcom/build/XPCOM.h
+++ b/xpcom/build/XPCOM.h
@@ -84,17 +84,16 @@
 #include "nsIMutable.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIOutputStream.h"
 #include "nsIProcess.h"
 #include "nsIProgrammingLanguage.h"
 #include "nsIProperties.h"
 #include "nsIPropertyBag2.h"
-#include "nsIRecyclingAllocator.h"
 #include "nsIRunnable.h"
 #include "nsISeekableStream.h"
 #include "nsISerializable.h"
 #include "nsIServiceManager.h"
 #include "nsIScriptableInputStream.h"
 #include "nsISimpleEnumerator.h"
 #include "nsISimpleUnicharStreamFactory.h"
 #include "nsIStreamBufferAccess.h"
--- a/xpcom/build/XPCOMModule.inc
+++ b/xpcom/build/XPCOMModule.inc
@@ -57,18 +57,16 @@
     COMPONENT(THREADPOOL, nsThreadPoolConstructor)
 
     COMPONENT(STRINGINPUTSTREAM, nsStringInputStreamConstructor)
     COMPONENT(MULTIPLEXINPUTSTREAM, nsMultiplexInputStreamConstructor)
 
     COMPONENT(VARIANT, nsVariantConstructor)
     COMPONENT(INTERFACEINFOMANAGER_SERVICE, nsXPTIInterfaceInfoManagerGetSingleton)
 
-    COMPONENT(RECYCLINGALLOCATOR, nsRecyclingAllocatorImplConstructor)
-
     COMPONENT(HASH_PROPERTY_BAG, nsHashPropertyBagConstructor)
 
     COMPONENT(UUID_GENERATOR, nsUUIDGeneratorConstructor)
 
 #if defined(XP_WIN)
     COMPONENT(WINDOWSREGKEY, nsWindowsRegKeyConstructor)
 #endif
 
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -112,18 +112,16 @@ extern nsresult nsStringInputStreamConst
 
 #include "nsUnicharInputStream.h"
 #include "nsVariant.h"
 
 #include "nsUUIDGenerator.h"
 
 #include "nsIOUtil.h"
 
-#include "nsRecyclingAllocator.h"
-
 #include "SpecialSystemDirectory.h"
 
 #if defined(XP_WIN)
 #include "nsWindowsRegKey.h"
 #endif
 
 #ifdef MOZ_WIDGET_COCOA
 #include "nsMacUtilsImpl.h"
@@ -203,18 +201,16 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerIm
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryOutputStream)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBinaryInputStream)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsStorageStream)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsVersionComparatorImpl)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptableBase64Encoder)
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsVariant)
 
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsRecyclingAllocatorImpl)
-
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHashPropertyBag, Init)
 
 NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsProperties, Init)
 
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUUIDGenerator, Init)
 
 #ifdef MOZ_WIDGET_COCOA
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacUtilsImpl)
--- a/xpcom/ds/Makefile.in
+++ b/xpcom/ds/Makefile.in
@@ -60,17 +60,16 @@ CPPSRCS		= \
 		nsHashPropertyBag.cpp \
 		nsHashSets.cpp \
 		nsHashtable.cpp \
 		nsINIParserImpl.cpp \
 		nsObserverList.cpp \
 		nsObserverService.cpp \
 		nsProperties.cpp \
 		nsPersistentProperties.cpp \
-		nsRecyclingAllocator.cpp \
 		nsStaticNameTable.cpp \
 		nsStringEnumerator.cpp \
 		nsSupportsArray.cpp \
 		nsSupportsArrayEnumerator.cpp \
 		nsSupportsPrimitives.cpp \
 		nsUnicharBuffer.cpp \
 		nsVariant.cpp \
 		$(NULL)
@@ -102,17 +101,16 @@ EXPORTS		= \
 		nsExpirationTracker.h \
 		nsFixedSizeAllocator.h \
 		nsHashSets.h \
 		nsHashtable.h \
 		nsIByteBuffer.h \
 		nsIUnicharBuffer.h \
 		nsMathUtils.h \
 		nsObserverService.h \
-		nsRecyclingAllocator.h \
 		nsStaticNameTable.h \
 		nsStaticAtom.h \
 		nsSupportsArray.h \
 		nsSupportsPrimitives.h \
 		nsVariant.h \
 		nsStringEnumerator.h \
 		nsHashPropertyBag.h \
 		nsWhitespaceTokenizer.h \
@@ -127,17 +125,16 @@ XPIDLSRCS	= \
 		nsIEnumerator.idl \
 		nsIINIParser.idl \
 		nsIPersistentProperties2.idl \
 		nsIProperty.idl \
 		nsIPropertyBag.idl \
 		nsIPropertyBag2.idl \
 		nsIWritablePropertyBag.idl \
 		nsIWritablePropertyBag2.idl \
-		nsIRecyclingAllocator.idl \
 		nsIVariant.idl \
 		nsISerializable.idl \
 		nsIStringEnumerator.idl \
 		nsISupportsArray.idl \
 		nsISupportsIterators.idl \
 		$(NULL)
 
 SDK_XPIDLSRCS   = \
deleted file mode 100644
--- a/xpcom/ds/nsIRecyclingAllocator.idl
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; 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) 2002
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Suresh Duddi <dp@netscape.com>
- *
- * 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 "nsIMemory.idl"
-
-/**
- *
- * nsIRecyclingAllocator: A wrapper for the nsRecyclingAllocator
- *
- * Holds allocations and reuses them for subsequent allocs.
- * Thread safe and uses a timer to release freelist.
- *
- * @status UNDER_DEVELOPMENT
- */
-
-[scriptable, uuid(d064a04c-9cee-4319-be31-64d565bccba9)]
-interface nsIRecyclingAllocator : nsIMemory
-{
-    void init(in size_t nblocks, in size_t recycleAfter, in string id);
-};
-
-%{C++
-#define NS_RECYCLINGALLOCATOR_CID \
-{ /* ac07ed4c-bf17-4976-a15c-d2194db3b1bf */ \
-    0xac07ed4c,                              \
-    0xbf17,                                  \
-    0x4976,                                  \
-    {0xa1, 0x5c, 0xd2, 0x19, 0x4d, 0xb3, 0xb1, 0xbf} }
-
-#define NS_RECYCLINGALLOCATOR_CLASSNAME "Recycling Allocator"
-
-#define NS_RECYCLINGALLOCATOR_CONTRACTID "@mozilla.org/recycling-allocator;1"
-%}
deleted file mode 100644
--- a/xpcom/ds/nsRecyclingAllocator.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-/* -*- Mode: C; tab-width: 4; 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) 2001, 2002
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *	Suresh Duddi <dp@netscape.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either 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 ***** */
-
-/*
- * nsRecyclingAllocator
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "nsRecyclingAllocator.h"
-#include "nsIMemory.h"
-#include "prprf.h"
-#include "nsITimer.h"
-
-using namespace mozilla;
-
-#define NS_SEC_TO_MS(s) ((s) * 1000)
-
-void
-nsRecyclingAllocator::nsRecycleTimerCallback(nsITimer *aTimer, void *aClosure)
-{
-    nsRecyclingAllocator *obj = (nsRecyclingAllocator *) aClosure;
-
-    MutexAutoLock lock(obj->mLock);
-
-    if (!obj->mTouched)
-    {
-        obj->ClearFreeList();
-    }
-    else
-    {
-        // Clear touched so the next time the timer fires we can test whether
-        // the allocator was used or not.
-        obj->mTouched = false;
-    }
-}
-
-
-nsRecyclingAllocator::nsRecyclingAllocator(PRUint32 nbucket, PRUint32 recycleAfter, const char *id) :
-    mMaxBlocks(nbucket), mFreeListCount(0), mFreeList(nsnull),
-    mLock("nsRecyclingAllocator.mLock"),
-    mRecycleTimer(nsnull), mRecycleAfter(recycleAfter), mTouched(false)
-#ifdef DEBUG
-    , mId(id), mNAllocated(0)
-#endif
-{
-}
-
-nsresult
-nsRecyclingAllocator::Init(PRUint32 nbucket, PRUint32 recycleAfter, const char *id)
-{
-    MutexAutoLock lock(mLock);
-
-    ClearFreeList();
-
-    // Reinitialize everything
-    mMaxBlocks = nbucket;
-    mRecycleAfter = recycleAfter;
-#ifdef DEBUG
-    mId = id;
-#endif
-
-    return NS_OK;
-}
-
-nsRecyclingAllocator::~nsRecyclingAllocator()
-{
-    ClearFreeList();
-}
-
-// Allocation and free routines
-void*
-nsRecyclingAllocator::Malloc(PRSize bytes, bool zeroit)
-{
-    // We don't enter lock for this check. This is intentional.
-    // Here is my logic: we are checking if (mFreeList). Doing this check
-    // without locking can lead to unpredictable results. YES. But the effect
-    // of the unpredictedness are ok. here is why:
-    //
-    // a) if the check returned NULL when there is stuff in freelist
-    //    We would just end up reallocating.
-    //
-    // b) if the check returned nonNULL when our freelist is empty
-    //    This is the more likely and dangerous case. The code for
-    //    FindFreeBlock() will enter lock, while (null) and return null.
-    //
-    // The reason why I chose to not enter lock for this check was that when
-    // there are no free blocks, we don't want to impose any more overhead than
-    // we already are for failing over to malloc/free.
-    if (mFreeList) {
-        MutexAutoLock lock(mLock);
-
-        // Mark that we are using. This will prevent any
-        // Timer based release of unused memory.
-        mTouched = true;
-
-        Block* freeNode = mFreeList;
-        Block** prevp = &mFreeList;
-
-        while (freeNode)
-        {
-            if (freeNode->bytes >= bytes)
-            {
-                // Found the best fit free block
-                // Remove this block from free list
-                *prevp = freeNode->next;
-                mFreeListCount --;
-
-                void *data = DATA(freeNode);
-                if (zeroit)
-                    memset(data, 0, bytes);
-                return data;
-            }
-
-            prevp = &(freeNode->next);
-            freeNode = freeNode->next;
-        }
-    }
-    
-    // We need to do an allocation
-    // Add 4 bytes to what we allocate to hold the bucket index
-    PRSize allocBytes = bytes + NS_ALLOCATOR_OVERHEAD_BYTES;
-
-    // Make sure it is big enough to hold the whole block
-    if (allocBytes < sizeof(Block)) allocBytes = sizeof(Block);
-
-    // We don't have that memory already. Allocate.
-    Block *ptr = (Block *) (zeroit ? calloc(1, allocBytes) : malloc(allocBytes));
-  
-    // Deal with no memory situation
-    if (!ptr)
-        return ptr;
-
-#ifdef DEBUG
-    mNAllocated++;
-#endif
-  
-    // Store size and return data portion
-    ptr->bytes = bytes;
-    return DATA(ptr);
-}
-
-void
-nsRecyclingAllocator::Free(void *ptr)
-{
-    Block* block = DATA_TO_BLOCK(ptr);
-
-    MutexAutoLock lock(mLock);
-
-    // Mark that we are using the allocator. This will prevent any
-    // timer based release of unused memory.
-    mTouched = true;
-
-    // Check on maximum number of blocks to keep in the freelist
-    if (mFreeListCount < mMaxBlocks) {
-        // Find the right spot in the sorted list.
-        Block* freeNode = mFreeList;
-        Block** prevp = &mFreeList;
-        while (freeNode)
-        {
-            if (freeNode->bytes >= block->bytes)
-                break;
-            prevp = &(freeNode->next);
-            freeNode = freeNode->next;
-        }
-
-        // Needs to be inserted between *prevp and freeNode
-        *prevp = block;
-        block->next = freeNode;
-        mFreeListCount ++;
-    } else {
-        // We are holding more than max. Failover to free
-#ifdef DEBUG_dp
-        char buf[1024];
-        // Warn if we are failing over to malloc/free and not storing it
-        // This says we have a misdesigned memory pool. The intent was
-        // once the pool was full, we would never fail over to calloc.
-        PR_snprintf(buf, sizeof(buf), "nsRecyclingAllocator(%s) FAILOVER 0x%p (%d) - %d allocations, %d max\n",
-                    mId, (char *)ptr, block->bytes, mNAllocated, mMaxBlocks);
-        NS_WARNING(buf);
-        mNAllocated--;
-#endif
-        free(block);
-    }
-
-    // Set up timer for releasing memory for blocks from the freelist.
-    // If this fails, then we won't have a timer to release unused
-    // memory. We can live with that. Also, the next Free
-    // will try again to set the timer.
-    if (mRecycleAfter && !mRecycleTimer)
-    {
-        // known only to stuff in xpcom.
-        extern nsresult NS_NewTimer(nsITimer* *aResult, nsTimerCallbackFunc aCallback, void *aClosure,
-                                    PRUint32 aDelay, PRUint32 aType);
-
-        (void) NS_NewTimer(&mRecycleTimer, nsRecycleTimerCallback, this,
-                           NS_SEC_TO_MS(mRecycleAfter),
-                           nsITimer::TYPE_REPEATING_SLACK);
-        // This can fail during xpcom shutdown
-        if (!mRecycleTimer)
-            NS_WARNING("nsRecyclingAllocator: Creating timer failed");
-    }
-}
-
-/* ClearFreeList
- *
- * Frees any bucket memory that isn't in use
- */
-
-void
-nsRecyclingAllocator::ClearFreeList()
-{
-#ifdef DEBUG_dp
-    printf("DEBUG: nsRecyclingAllocator(%s) ClearFreeList (%d): ", mId, mFreeListCount);
-#endif
-    // Cancel the timer, because the freelist will be forcefully cleared after this.
-    // We will revive the timer on the next allocation.
-    // XXX Unfortunately there is no way to Cancel and restart the same timer.
-    // XXX So we pretty much kill it and create a new one later.
-    if (mRecycleTimer)
-    {
-        mRecycleTimer->Cancel();
-        NS_RELEASE(mRecycleTimer);
-    }
-
-    // We will run through the freelist and free all blocks
-    Block* node = mFreeList;
-    while (node)
-    {
-#ifdef DEBUG_dp
-        printf("%d ", node->bytes);
-#endif
-        Block *next = node->next;
-        free(node);
-        node = next;
-    }
-    mFreeList = nsnull;
-    mFreeListCount = 0;
-
-#ifdef DEBUG
-    mNAllocated = 0;
-#endif
-#ifdef DEBUG_dp
-    printf("\n");
-#endif
-}
-
-
-// ----------------------------------------------------------------------
-// Wrapping the recyling allocator with nsIMemory
-// ----------------------------------------------------------------------
-
-// nsIMemory methods
-NS_IMPL_THREADSAFE_ISUPPORTS2(nsRecyclingAllocatorImpl, nsIMemory, nsIRecyclingAllocator)
-
-NS_IMETHODIMP_(void *)
-nsRecyclingAllocatorImpl::Alloc(PRSize size)
-{
-    return nsRecyclingAllocatorImpl::Malloc(size, false);
-}
-
-NS_IMETHODIMP_(void *)
-nsRecyclingAllocatorImpl::Realloc(void *ptr, PRSize size)
-{
-    // XXX Not yet implemented
-    return NULL;
-}
-
-NS_IMETHODIMP_(void)
-nsRecyclingAllocatorImpl::Free(void *ptr)
-{
-    nsRecyclingAllocator::Free(ptr);
-}
-
-NS_IMETHODIMP
-nsRecyclingAllocatorImpl::Init(size_t nbuckets, size_t recycleAfter, const char *id)
-{
-    return nsRecyclingAllocator::Init((PRUint32) nbuckets, (PRUint32) recycleAfter, id);
-}
-
-NS_IMETHODIMP
-nsRecyclingAllocatorImpl::HeapMinimize(bool immediate)
-{
-    // XXX Not yet implemented
-    return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsRecyclingAllocatorImpl::IsLowMemory(bool *lowmemoryb_ptr)
-{
-    // XXX Not yet implemented
-    return NS_ERROR_NOT_IMPLEMENTED;
-}
-
deleted file mode 100644
--- a/xpcom/ds/nsRecyclingAllocator.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** 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) 2001, 2002
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *	Suresh Duddi <dp@netscape.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either 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 ***** */
-
-/*
- * nsRecyclingAllocator
- *
- * This allocator is useful when we cycle through a small set of allocations
- * repeatedly with minimal overlap. For eg. something we do for every gif
- * file read (or) buffers required for decompression of every file from jar.
- *
- * What this does is keeps around the first set of memory allocated and
- * reuses it subsequently. If all buckets are full, this falls back to
- * malloc/free
- *
- * Uses a timer to release all memory allocated if not used for more than
- * 10 secs automatically.
- *
- * Also there is a 4 byte maintenance overhead on every allocation.
- *
- * This allocator is thread safe.
- *
- * CAVEATS: As the number of buckets increases, this allocators performance
- *          will drop, as the list of freed items is a linked list sorted on size.
- */
-
-#ifndef nsRecyclingAllocator_h__
-#define nsRecyclingAllocator_h__
-
-#include "mozilla/Mutex.h"
-#include "nscore.h"
-#include "nsIRecyclingAllocator.h"
-
-#define NS_DEFAULT_RECYCLE_TIMEOUT 10  // secs
-#define NS_ALLOCATOR_OVERHEAD_BYTES (sizeof(PRSize)) // bytes
-
-class nsITimer;
-class nsIMemory;
-
-class nsRecyclingAllocator {
- protected:
-    struct Block {
-      PRSize bytes;
-      Block *next;
-    };
-
-#define DATA(block) ((void *)(((char *)block) + NS_ALLOCATOR_OVERHEAD_BYTES))
-#define DATA_TO_BLOCK(data) ((Block *)((char *)(data) - NS_ALLOCATOR_OVERHEAD_BYTES))
-
-    // mMaxBlocks: Maximum number of blocks that are kept in the mFreeList for recycling
-    PRUint32 mMaxBlocks;
-
-    // mFreeListCount: Current number of blocks in the mFreeList
-    PRUint32 mFreeListCount;
-
-    // mFreeList: linked list of free blocks sorted by increasing order of size
-    Block* mFreeList;
-
-    // mLock: Thread safety for the member variables:
-    //  mFreeList, mFreeListCount, mRecycleTimer, and mTouched
-    mozilla::Mutex mLock;
-
-    // Timer for freeing unused memory
-    nsITimer *mRecycleTimer;
-
-    // mRecycleAfter:
-    //  Allocator should be untouched for this many seconds for freeing
-    //  unused Blocks.
-    PRUint32 mRecycleAfter;
-
-    // mTouched:
-    //  says if the allocator touched the freelist. If allocator didn't touch
-    //  the freelist over a time time interval, timer will call ClearFreeList()
-    bool mTouched;
-
-#ifdef DEBUG
-    // mId:
-    //  a string for identifying the user of nsRecyclingAllocator
-    //  User mainly for debug prints
-    const char *mId;
-
-    // mNAllocated: Number of blocks allocated
-    PRInt32 mNAllocated;
-#endif
-
- public:
-
-    // nbucket : number of buckets to hold. Capped at NS_MAX_BUCKET
-    // recycleAfter : Try recycling allocated buckets after this many seconds
-    // id : a string used to identify debug prints. Will not be released.
-    nsRecyclingAllocator(PRUint32 nbucket = 0, PRUint32 recycleAfter = NS_DEFAULT_RECYCLE_TIMEOUT,
-                         const char *id = NULL);
-    ~nsRecyclingAllocator();
-
-    nsresult Init(PRUint32 nbucket, PRUint32 recycleAfter, const char *id);
-
-    // Allocation and free routines
-    void* Malloc(PRSize size, bool zeroit = false);
-    void  Free(void *ptr);
-
-    void* Calloc(PRUint32 items, PRSize size)
-    {
-        return Malloc(items * size, true);
-    }
-
-    // ClearFreeList - Frees all blocks kept by mFreelist, and stops the timer
-    void ClearFreeList();
-
- protected:
-
-    // Timer callback to trigger unused memory
-    static void nsRecycleTimerCallback(nsITimer *aTimer, void *aClosure);
-    friend void nsRecycleTimerCallback(nsITimer *aTimer, void *aClosure);
-};
-
-// ----------------------------------------------------------------------
-// Wrapping the recyling allocator with nsIMemory
-// ----------------------------------------------------------------------
-
-// Wrapping the nsRecyclingAllocator with nsIMemory
-class nsRecyclingAllocatorImpl : public nsRecyclingAllocator, public nsIRecyclingAllocator {
-public:
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIMEMORY
-    NS_DECL_NSIRECYCLINGALLOCATOR
-
-    nsRecyclingAllocatorImpl()
-    {
-    }
-
-private:
-    ~nsRecyclingAllocatorImpl() {}
-};
-#endif // nsRecyclingAllocator_h__