diff --git a/xpcom/build/XPCOM.h b/xpcom/build/XPCOM.h index 47679da8da5d..9366cec37e33 100644 --- a/xpcom/build/XPCOM.h +++ b/xpcom/build/XPCOM.h @@ -89,7 +89,6 @@ #include "nsIProgrammingLanguage.h" #include "nsIProperties.h" #include "nsIPropertyBag2.h" -#include "nsIRecyclingAllocator.h" #include "nsIRunnable.h" #include "nsISeekableStream.h" #include "nsISerializable.h" diff --git a/xpcom/build/XPCOMModule.inc b/xpcom/build/XPCOMModule.inc index 39bb69272471..98bed2bfd919 100644 --- a/xpcom/build/XPCOMModule.inc +++ b/xpcom/build/XPCOMModule.inc @@ -62,8 +62,6 @@ COMPONENT(VARIANT, nsVariantConstructor) COMPONENT(INTERFACEINFOMANAGER_SERVICE, nsXPTIInterfaceInfoManagerGetSingleton) - COMPONENT(RECYCLINGALLOCATOR, nsRecyclingAllocatorImplConstructor) - COMPONENT(HASH_PROPERTY_BAG, nsHashPropertyBagConstructor) COMPONENT(UUID_GENERATOR, nsUUIDGeneratorConstructor) diff --git a/xpcom/build/nsXPComInit.cpp b/xpcom/build/nsXPComInit.cpp index 0abf49ec71cd..ec672651aa97 100644 --- a/xpcom/build/nsXPComInit.cpp +++ b/xpcom/build/nsXPComInit.cpp @@ -117,8 +117,6 @@ extern nsresult nsStringInputStreamConstructor(nsISupports *, REFNSIID, void **) #include "nsIOUtil.h" -#include "nsRecyclingAllocator.h" - #include "SpecialSystemDirectory.h" #if defined(XP_WIN) @@ -208,8 +206,6 @@ 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) diff --git a/xpcom/ds/Makefile.in b/xpcom/ds/Makefile.in index 09d6b5bdc8f7..ca33f4258662 100644 --- a/xpcom/ds/Makefile.in +++ b/xpcom/ds/Makefile.in @@ -65,7 +65,6 @@ CPPSRCS = \ nsObserverService.cpp \ nsProperties.cpp \ nsPersistentProperties.cpp \ - nsRecyclingAllocator.cpp \ nsStaticNameTable.cpp \ nsStringEnumerator.cpp \ nsSupportsArray.cpp \ @@ -107,7 +106,6 @@ EXPORTS = \ nsIUnicharBuffer.h \ nsMathUtils.h \ nsObserverService.h \ - nsRecyclingAllocator.h \ nsStaticNameTable.h \ nsStaticAtom.h \ nsSupportsArray.h \ @@ -132,7 +130,6 @@ XPIDLSRCS = \ nsIPropertyBag2.idl \ nsIWritablePropertyBag.idl \ nsIWritablePropertyBag2.idl \ - nsIRecyclingAllocator.idl \ nsIVariant.idl \ nsISerializable.idl \ nsIStringEnumerator.idl \ diff --git a/xpcom/ds/nsIRecyclingAllocator.idl b/xpcom/ds/nsIRecyclingAllocator.idl deleted file mode 100644 index 22557459cf60..000000000000 --- 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 - * - * 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" -%} diff --git a/xpcom/ds/nsRecyclingAllocator.cpp b/xpcom/ds/nsRecyclingAllocator.cpp deleted file mode 100644 index cfda6bc5168e..000000000000 --- 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 - * - * 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 -#include -#include -#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; -} - diff --git a/xpcom/ds/nsRecyclingAllocator.h b/xpcom/ds/nsRecyclingAllocator.h deleted file mode 100644 index 0caa3d74d478..000000000000 --- 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 - * - * 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__