Bug 715770 (part 3) - Remove nsRecyclingAllocator. r=bsmedberg.
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 17 Jan 2012 17:29:52 -0800
changeset 85990 3b8dd350dbab3c8f6322920a2a50704a2ce04a13
parent 85989 7fe6463d454786c023235a4b1da4f66d45fae4c3
child 85991 b105fa66bb3707858f9ab67cfbf40e0c41c51fbf
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs715770
milestone12.0a1
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__