Removed size args from nsIAllocator Realloc and Free. Now nsPageMgr keeps track of sizes for its nsIAllocator interface.

git-svn-id: svn://10.0.0.236/trunk@30682 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
warren%netscape.com
1999-05-07 06:22:11 +00:00
parent 02cc12bd76
commit 40cb5e5fad
12 changed files with 140 additions and 90 deletions

View File

@@ -110,7 +110,7 @@ nsBuffer::PopReadSegment()
mBufferSize -= mGrowBySize;
rv = mAllocator->Free(segment, mGrowBySize);
rv = mAllocator->Free(segment);
if (NS_FAILED(rv)) return rv;
// initialize the read segment

View File

@@ -39,7 +39,7 @@
/******************************************************************************/
#define NS_PAGEMGR_CLUSTERDESC_CLUMPSIZE 1
#define NS_PAGEMGR_CLUSTERDESC_CLUMPSIZE 16
void
nsPageMgr::DeleteFreeClusterDesc(nsClusterDesc *desc)
@@ -346,10 +346,10 @@ nsPageMgr::FinalizePages()
nsPageMgr::nsPageMgr()
: mUnusedClusterDescs(nsnull),
mFreeClusters(nsnull),
mInUseClusters(nsnull),
mMonitor(nsnull),
mMemoryBase(nsnull),
mBoundary(nsnull),
mPageCount(0),
#ifdef XP_PC
mLastPageFreed(nsnull),
mLastPageFreedSize(0),
@@ -367,7 +367,7 @@ nsPageMgr::nsPageMgr()
mSegTable(nsnull),
mSegTableCount(0),
#endif
mAlreadyLocked(PR_FALSE)
mPageCount(0)
{
NS_INIT_REFCNT();
}
@@ -380,7 +380,6 @@ nsPageMgr::Init(nsPageCount minPages, nsPageCount maxPages)
mMonitor = PR_NewMonitor();
if (mMonitor == NULL)
return PR_FAILURE;
mAlreadyLocked = PR_FALSE;
status = InitPages(minPages, maxPages);
if (status != PR_SUCCESS)
@@ -391,6 +390,7 @@ nsPageMgr::Init(nsPageCount minPages, nsPageCount maxPages)
PR_ASSERT(mBoundary);
mFreeClusters = NULL;
mInUseClusters = NULL;
return status == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE;
}
@@ -582,11 +582,10 @@ nsPageMgr::NS_PAGEMGR_DECOMMIT_CLUSTER(void* addr, PRUword size)
nsPage*
nsPageMgr::NewCluster(nsPageCount nPages)
{
nsPage* addr;
nsAutoMonitor mon(mMonitor);
nsPage* addr;
PR_ASSERT(nPages > 0);
if (!mAlreadyLocked)
PR_EnterMonitor(mMonitor);
addr = AllocClusterFromFreeList(nPages);
if (!addr && mBoundary + nPages <= mMemoryBase + mPageCount) {
addr = mBoundary;
@@ -609,14 +608,14 @@ nsPageMgr::NewCluster(nsPageCount nPages)
}
DBG_MEMSET(addr, NS_PAGEMGR_PAGE_ALLOC_PATTERN, size);
}
if (!mAlreadyLocked)
PR_ExitMonitor(mMonitor);
return (nsPage*)addr;
}
void
nsPageMgr::DestroyCluster(nsPage* basePage, nsPageCount nPages)
{
nsAutoMonitor mon(mMonitor);
int freeResult;
PRUword size = nPages << NS_PAGEMGR_PAGE_BITS;
@@ -627,8 +626,6 @@ nsPageMgr::DestroyCluster(nsPage* basePage, nsPageCount nPages)
DBG_MEMSET(basePage, NS_PAGEMGR_PAGE_FREE_PATTERN, size);
freeResult = NS_PAGEMGR_DECOMMIT_CLUSTER((void*)basePage, size);
PR_ASSERT(freeResult);
if (!mAlreadyLocked)
PR_EnterMonitor(mMonitor);
if (basePage + nPages == mBoundary) {
nsClusterDesc **p;
nsClusterDesc *desc;
@@ -655,8 +652,6 @@ nsPageMgr::DestroyCluster(nsPage* basePage, nsPageCount nPages)
#ifdef NS_PAGEMGR_VERIFYCLUSTERS
VerifyClusters(-(PRWord)nPages);
#endif
if (!mAlreadyLocked)
PR_ExitMonitor(mMonitor);
}
////////////////////////////////////////////////////////////////////////////////
@@ -682,34 +677,75 @@ nsPageMgr::DeallocPages(PRUint32 pageCount, void* pages)
////////////////////////////////////////////////////////////////////////////////
// nsIAllocator methods:
//
// Note: nsIAllocator needs to keep track of the size of the blocks it allocates
// whereas, nsIPageManager doesn't. That means that there's a little extra
// overhead for users of this interface. It also means that things allocated
// with the nsIPageManager interface can't be freed with the nsIAllocator
// interface and vice versa.
NS_IMETHODIMP_(void*)
nsPageMgr::Alloc(PRUint32 size)
{
nsAutoMonitor mon(mMonitor);
nsresult rv;
void* page;
rv = AllocPages(NS_PAGEMGR_PAGE_COUNT(size), &page);
if (NS_FAILED(rv)) return nsnull;
void* page = nsnull;
PRUint32 pageCount = NS_PAGEMGR_PAGE_COUNT(size);
rv = AllocPages(pageCount, &page);
if (NS_FAILED(rv))
return nsnull;
// Add this cluster to the mInUseClusters list:
nsClusterDesc* desc = NewFreeClusterDesc();
if (desc == nsnull) {
rv = DeallocPages(pageCount, page);
NS_ASSERTION(NS_SUCCEEDED(rv), "DeallocPages failed");
return nsnull;
}
desc->mAddr = (nsPage*)page;
desc->mPageCount = pageCount;
desc->mNext = mInUseClusters;
mInUseClusters = desc;
return page;
}
NS_IMETHODIMP_(void*)
nsPageMgr::Realloc(void* ptr, PRUint32 size, PRInt32 oldSize)
nsPageMgr::Realloc(void* ptr, PRUint32 size)
{
// XXX This realloc implementation could be made smarter by trying to
// append to the current block, but I don't think we really care right now.
nsresult rv;
rv = Free(ptr, oldSize);
rv = Free(ptr);
if (NS_FAILED(rv)) return nsnull;
void* newPtr = Alloc(size);
return newPtr;
}
NS_IMETHODIMP
nsPageMgr::Free(void* ptr, PRInt32 size)
nsPageMgr::Free(void* ptr)
{
nsresult rv;
NS_ASSERTION(size != -1, "unspecified oldSize");
rv = DeallocPages(NS_PAGEMGR_PAGE_COUNT(size), ptr);
return rv;
nsAutoMonitor mon(mMonitor);
PR_ASSERT(NS_PAGEMGR_IS_ALIGNED(ptr, NS_PAGEMGR_PAGE_BITS));
// Remove the cluster from the mInUseClusters list:
nsClusterDesc** list = &mInUseClusters;
nsClusterDesc* desc;
while ((desc = *list) != nsnull) {
if (desc->mAddr == ptr) {
// found -- unlink the desc and free it
*list = desc->mNext;
nsresult rv = DeallocPages(desc->mPageCount, ptr);
DeleteFreeClusterDesc(desc);
return rv;
}
list = &desc->mNext;
}
NS_ASSERTION(0, "memory not allocated with nsPageMgr::Alloc");
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP

View File

@@ -23,7 +23,7 @@
#include "nsIAllocator.h"
#include "nscore.h"
#include "prmon.h"
#include "nsAutoLock.h"
#include "prlog.h"
#ifdef XP_MAC
#include <Types.h>
@@ -108,9 +108,8 @@ class nsPageMgr : public nsIPageManager, public nsIAllocator {
// nsIAllocator methods:
NS_IMETHOD_(void*) Alloc(PRUint32 size);
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size,
PRInt32 oldSize = -1);
NS_IMETHOD Free(void* ptr, PRInt32 size = -1);
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size);
NS_IMETHOD Free(void* ptr);
NS_IMETHOD HeapMinimize(void);
// nsPageMgr methods:
@@ -149,6 +148,7 @@ class nsPageMgr : public nsIPageManager, public nsIAllocator {
protected:
nsClusterDesc* mUnusedClusterDescs;
nsClusterDesc* mFreeClusters;
nsClusterDesc* mInUseClusters; // used by nsIAllocator methods
PRMonitor* mMonitor;
nsPage* mMemoryBase;
nsPage* mBoundary;
@@ -178,8 +178,6 @@ class nsPageMgr : public nsIPageManager, public nsIAllocator {
nsSegmentDesc* mSegTable;
PRWord mSegTableCount;
#endif
PRBool mAlreadyLocked;
};
/******************************************************************************/

View File

@@ -78,14 +78,13 @@ nsAllocatorImpl::Alloc(PRUint32 size)
}
NS_METHOD_(void*)
nsAllocatorImpl::Realloc(void* ptr, PRUint32 size,
PRInt32 oldSize)
nsAllocatorImpl::Realloc(void* ptr, PRUint32 size)
{
return PR_Realloc(ptr, size);
}
NS_METHOD
nsAllocatorImpl::Free(void* ptr, PRInt32 size)
nsAllocatorImpl::Free(void* ptr)
{
PR_Free(ptr);
return NS_OK;

View File

@@ -45,20 +45,16 @@ public:
*
* @param ptr - the block of memory to reallocate
* @param size - the new size
* @param oldSize - the current size of the block. If -1 (the default),
* the implementation must be able to determine the block size by
* examining the block pointer.
* @result the rellocated block of memory
*/
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size,
PRInt32 oldSize = -1);
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size);
/**
* Frees a block of memory.
*
* @param ptr - the block of memory to free
*/
NS_IMETHOD Free(void* ptr, PRInt32 size = -1);
NS_IMETHOD Free(void* ptr);
/**
* Attempts to shrink the heap.

View File

@@ -51,13 +51,9 @@ public:
*
* @param ptr - the block of memory to reallocate
* @param size - the new size
* @param oldSize - the current size of the block. If -1 (the default),
* the implementation must be able to determine the block size by
* examining the block pointer.
* @result the rellocated block of memory
*/
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size,
PRInt32 oldSize = -1) = 0;
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size) = 0;
/**
* Frees a block of memory.
@@ -67,7 +63,7 @@ public:
* the implementation must be able to determine the block size by
* examining the block pointer.
*/
NS_IMETHOD Free(void* ptr, PRInt32 size = -1) = 0;
NS_IMETHOD Free(void* ptr) = 0;
/**
* Attempts to shrink the heap.

View File

@@ -110,7 +110,7 @@ nsBuffer::PopReadSegment()
mBufferSize -= mGrowBySize;
rv = mAllocator->Free(segment, mGrowBySize);
rv = mAllocator->Free(segment);
if (NS_FAILED(rv)) return rv;
// initialize the read segment

View File

@@ -39,7 +39,7 @@
/******************************************************************************/
#define NS_PAGEMGR_CLUSTERDESC_CLUMPSIZE 1
#define NS_PAGEMGR_CLUSTERDESC_CLUMPSIZE 16
void
nsPageMgr::DeleteFreeClusterDesc(nsClusterDesc *desc)
@@ -346,10 +346,10 @@ nsPageMgr::FinalizePages()
nsPageMgr::nsPageMgr()
: mUnusedClusterDescs(nsnull),
mFreeClusters(nsnull),
mInUseClusters(nsnull),
mMonitor(nsnull),
mMemoryBase(nsnull),
mBoundary(nsnull),
mPageCount(0),
#ifdef XP_PC
mLastPageFreed(nsnull),
mLastPageFreedSize(0),
@@ -367,7 +367,7 @@ nsPageMgr::nsPageMgr()
mSegTable(nsnull),
mSegTableCount(0),
#endif
mAlreadyLocked(PR_FALSE)
mPageCount(0)
{
NS_INIT_REFCNT();
}
@@ -380,7 +380,6 @@ nsPageMgr::Init(nsPageCount minPages, nsPageCount maxPages)
mMonitor = PR_NewMonitor();
if (mMonitor == NULL)
return PR_FAILURE;
mAlreadyLocked = PR_FALSE;
status = InitPages(minPages, maxPages);
if (status != PR_SUCCESS)
@@ -391,6 +390,7 @@ nsPageMgr::Init(nsPageCount minPages, nsPageCount maxPages)
PR_ASSERT(mBoundary);
mFreeClusters = NULL;
mInUseClusters = NULL;
return status == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE;
}
@@ -582,11 +582,10 @@ nsPageMgr::NS_PAGEMGR_DECOMMIT_CLUSTER(void* addr, PRUword size)
nsPage*
nsPageMgr::NewCluster(nsPageCount nPages)
{
nsPage* addr;
nsAutoMonitor mon(mMonitor);
nsPage* addr;
PR_ASSERT(nPages > 0);
if (!mAlreadyLocked)
PR_EnterMonitor(mMonitor);
addr = AllocClusterFromFreeList(nPages);
if (!addr && mBoundary + nPages <= mMemoryBase + mPageCount) {
addr = mBoundary;
@@ -609,14 +608,14 @@ nsPageMgr::NewCluster(nsPageCount nPages)
}
DBG_MEMSET(addr, NS_PAGEMGR_PAGE_ALLOC_PATTERN, size);
}
if (!mAlreadyLocked)
PR_ExitMonitor(mMonitor);
return (nsPage*)addr;
}
void
nsPageMgr::DestroyCluster(nsPage* basePage, nsPageCount nPages)
{
nsAutoMonitor mon(mMonitor);
int freeResult;
PRUword size = nPages << NS_PAGEMGR_PAGE_BITS;
@@ -627,8 +626,6 @@ nsPageMgr::DestroyCluster(nsPage* basePage, nsPageCount nPages)
DBG_MEMSET(basePage, NS_PAGEMGR_PAGE_FREE_PATTERN, size);
freeResult = NS_PAGEMGR_DECOMMIT_CLUSTER((void*)basePage, size);
PR_ASSERT(freeResult);
if (!mAlreadyLocked)
PR_EnterMonitor(mMonitor);
if (basePage + nPages == mBoundary) {
nsClusterDesc **p;
nsClusterDesc *desc;
@@ -655,8 +652,6 @@ nsPageMgr::DestroyCluster(nsPage* basePage, nsPageCount nPages)
#ifdef NS_PAGEMGR_VERIFYCLUSTERS
VerifyClusters(-(PRWord)nPages);
#endif
if (!mAlreadyLocked)
PR_ExitMonitor(mMonitor);
}
////////////////////////////////////////////////////////////////////////////////
@@ -682,34 +677,75 @@ nsPageMgr::DeallocPages(PRUint32 pageCount, void* pages)
////////////////////////////////////////////////////////////////////////////////
// nsIAllocator methods:
//
// Note: nsIAllocator needs to keep track of the size of the blocks it allocates
// whereas, nsIPageManager doesn't. That means that there's a little extra
// overhead for users of this interface. It also means that things allocated
// with the nsIPageManager interface can't be freed with the nsIAllocator
// interface and vice versa.
NS_IMETHODIMP_(void*)
nsPageMgr::Alloc(PRUint32 size)
{
nsAutoMonitor mon(mMonitor);
nsresult rv;
void* page;
rv = AllocPages(NS_PAGEMGR_PAGE_COUNT(size), &page);
if (NS_FAILED(rv)) return nsnull;
void* page = nsnull;
PRUint32 pageCount = NS_PAGEMGR_PAGE_COUNT(size);
rv = AllocPages(pageCount, &page);
if (NS_FAILED(rv))
return nsnull;
// Add this cluster to the mInUseClusters list:
nsClusterDesc* desc = NewFreeClusterDesc();
if (desc == nsnull) {
rv = DeallocPages(pageCount, page);
NS_ASSERTION(NS_SUCCEEDED(rv), "DeallocPages failed");
return nsnull;
}
desc->mAddr = (nsPage*)page;
desc->mPageCount = pageCount;
desc->mNext = mInUseClusters;
mInUseClusters = desc;
return page;
}
NS_IMETHODIMP_(void*)
nsPageMgr::Realloc(void* ptr, PRUint32 size, PRInt32 oldSize)
nsPageMgr::Realloc(void* ptr, PRUint32 size)
{
// XXX This realloc implementation could be made smarter by trying to
// append to the current block, but I don't think we really care right now.
nsresult rv;
rv = Free(ptr, oldSize);
rv = Free(ptr);
if (NS_FAILED(rv)) return nsnull;
void* newPtr = Alloc(size);
return newPtr;
}
NS_IMETHODIMP
nsPageMgr::Free(void* ptr, PRInt32 size)
nsPageMgr::Free(void* ptr)
{
nsresult rv;
NS_ASSERTION(size != -1, "unspecified oldSize");
rv = DeallocPages(NS_PAGEMGR_PAGE_COUNT(size), ptr);
return rv;
nsAutoMonitor mon(mMonitor);
PR_ASSERT(NS_PAGEMGR_IS_ALIGNED(ptr, NS_PAGEMGR_PAGE_BITS));
// Remove the cluster from the mInUseClusters list:
nsClusterDesc** list = &mInUseClusters;
nsClusterDesc* desc;
while ((desc = *list) != nsnull) {
if (desc->mAddr == ptr) {
// found -- unlink the desc and free it
*list = desc->mNext;
nsresult rv = DeallocPages(desc->mPageCount, ptr);
DeleteFreeClusterDesc(desc);
return rv;
}
list = &desc->mNext;
}
NS_ASSERTION(0, "memory not allocated with nsPageMgr::Alloc");
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP

View File

@@ -23,7 +23,7 @@
#include "nsIAllocator.h"
#include "nscore.h"
#include "prmon.h"
#include "nsAutoLock.h"
#include "prlog.h"
#ifdef XP_MAC
#include <Types.h>
@@ -108,9 +108,8 @@ class nsPageMgr : public nsIPageManager, public nsIAllocator {
// nsIAllocator methods:
NS_IMETHOD_(void*) Alloc(PRUint32 size);
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size,
PRInt32 oldSize = -1);
NS_IMETHOD Free(void* ptr, PRInt32 size = -1);
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size);
NS_IMETHOD Free(void* ptr);
NS_IMETHOD HeapMinimize(void);
// nsPageMgr methods:
@@ -149,6 +148,7 @@ class nsPageMgr : public nsIPageManager, public nsIAllocator {
protected:
nsClusterDesc* mUnusedClusterDescs;
nsClusterDesc* mFreeClusters;
nsClusterDesc* mInUseClusters; // used by nsIAllocator methods
PRMonitor* mMonitor;
nsPage* mMemoryBase;
nsPage* mBoundary;
@@ -178,8 +178,6 @@ class nsPageMgr : public nsIPageManager, public nsIAllocator {
nsSegmentDesc* mSegTable;
PRWord mSegTableCount;
#endif
PRBool mAlreadyLocked;
};
/******************************************************************************/

View File

@@ -51,13 +51,9 @@ public:
*
* @param ptr - the block of memory to reallocate
* @param size - the new size
* @param oldSize - the current size of the block. If -1 (the default),
* the implementation must be able to determine the block size by
* examining the block pointer.
* @result the rellocated block of memory
*/
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size,
PRInt32 oldSize = -1) = 0;
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size) = 0;
/**
* Frees a block of memory.
@@ -67,7 +63,7 @@ public:
* the implementation must be able to determine the block size by
* examining the block pointer.
*/
NS_IMETHOD Free(void* ptr, PRInt32 size = -1) = 0;
NS_IMETHOD Free(void* ptr) = 0;
/**
* Attempts to shrink the heap.

View File

@@ -78,14 +78,13 @@ nsAllocatorImpl::Alloc(PRUint32 size)
}
NS_METHOD_(void*)
nsAllocatorImpl::Realloc(void* ptr, PRUint32 size,
PRInt32 oldSize)
nsAllocatorImpl::Realloc(void* ptr, PRUint32 size)
{
return PR_Realloc(ptr, size);
}
NS_METHOD
nsAllocatorImpl::Free(void* ptr, PRInt32 size)
nsAllocatorImpl::Free(void* ptr)
{
PR_Free(ptr);
return NS_OK;

View File

@@ -45,20 +45,16 @@ public:
*
* @param ptr - the block of memory to reallocate
* @param size - the new size
* @param oldSize - the current size of the block. If -1 (the default),
* the implementation must be able to determine the block size by
* examining the block pointer.
* @result the rellocated block of memory
*/
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size,
PRInt32 oldSize = -1);
NS_IMETHOD_(void*) Realloc(void* ptr, PRUint32 size);
/**
* Frees a block of memory.
*
* @param ptr - the block of memory to free
*/
NS_IMETHOD Free(void* ptr, PRInt32 size = -1);
NS_IMETHOD Free(void* ptr);
/**
* Attempts to shrink the heap.