Fix a bug in the Mac memory allocators which caused large heap allocations to be slow (r=beard), and tweaked the allocator sizes so that the fixed heap allocators catch some peak sizes (r=pinkerton). Also made minor tweaks to fix stats collection, and building of various testing tools.

This commit is contained in:
sfraser%netscape.com 2000-08-30 05:36:17 +00:00
Родитель 2613d8a8bd
Коммит c7d952aa91
9 изменённых файлов: 61 добавлений и 27 удалений

Просмотреть файл

@ -11,23 +11,10 @@
### Symbols you may have to hand annotate with #{code} or #{data}...
###
#CallCacheFlushers
#Flush_Allocate
#Flush_Free
#Flush_Reallocate
#InstallGarbageCollectorCacheFlusher
#InstallMallocHeapLowProc
#InstallMemoryCacheFlusher
#Memory_ReserveInMacHeap
calloc
free
malloc
#memsize
#memtotal
realloc
#{data}
#gFastMemSmallSizeAllocators
###
### Symbols which do not require hand annotation...

Двоичные данные
lib/mac/MacMemoryAllocator/MemAllocator.mcp

Двоичный файл не отображается.

Просмотреть файл

@ -28,3 +28,4 @@
#include "MemAllocatorConfig.h"
#pragma profile on

Просмотреть файл

@ -194,8 +194,8 @@ nsAllocatorManager::nsAllocatorManager()
, mLastHeapZone(nil)
//--------------------------------------------------------------------
{
mMinSmallBlockSize = 129; //128; //44; // some magic numbers for now
mMinLargeBlockSize = 256; //512; //256;
mMinSmallBlockSize = 165; //128; //44; // some magic numbers for now
mMinLargeBlockSize = 261; //512; //256;
mNumFixedSizeAllocators = mMinSmallBlockSize / 4;
mNumSmallBlockAllocators = 1 + (mMinLargeBlockSize - mMinSmallBlockSize) / kSmallHeapByteRange;
@ -484,7 +484,7 @@ void nsAllocatorManager::DumpMemoryStats()
// Enter a valid, UNIX-style full path on your system to get this
// to work.
outFile = PR_Open("/System/MemoryStats.txt", PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, 0644);
outFile = PR_Open("MemoryStats.txt", PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, 0644);
if ( outFile == NULL )
{
return;

Просмотреть файл

@ -53,13 +53,17 @@ void * nsLargeHeapAllocator::AllocatorMakeBlock(size_t blockSize)
nsLargeHeapChunk* chunk = (nsLargeHeapChunk *)mFirstChunk;
LargeBlockHeader *theBlock = nil;
UInt32 allocSize = GetPaddedBlockSize(blockSize);
// walk through all of our chunks, trying to allocate memory from somewhere
while (chunk)
{
theBlock = chunk->GetSpaceForBlock(blockSize);
if (theBlock)
break;
if (chunk->GetLargestFreeBlock() >= allocSize)
{
theBlock = chunk->GetSpaceForBlock(blockSize);
if (theBlock)
break;
}
chunk = (nsLargeHeapChunk *)chunk->GetNextChunk();
}
@ -221,6 +225,14 @@ nsLargeHeapChunk::nsLargeHeapChunk(
LargeBlockHeader *freeBlock = mHead->SkipDummyBlock();
mHead->SetNextBlock(freeBlock);
mHead->SetLogicalSize(0);
#if DEBUG_HEAP_INTEGRITY
mHead->SetPaddingBytes(0);
mHead->SetHeaderTag(kDummyBlockHeaderTag);
mHead->header.blockID = -1;
#endif
freeBlock->SetPrevBlock(nil);
freeBlock->SetNextBlock( (LargeBlockHeader *) ( (UInt32)freeBlock + heapSize - 2 * LargeBlockHeader::kLargeBlockOverhead) );
@ -497,16 +509,18 @@ void nsLargeHeapChunk::ReturnBlock(LargeBlockHeader *deadBlock)
void nsLargeHeapChunk::UpdateLargestFreeBlock()
//--------------------------------------------------------------------
{
LargeBlockHeader *thisBlock = mHead;
LargeBlockHeader *thisBlock = mHead->GetNextBlock(); // head block is a dummy block
UInt32 curMaxSize = 0;
while (thisBlock != mTail)
{
UInt32 blockSize = thisBlock->GetBlockHeapUsageSize();
if (blockSize > curMaxSize)
curMaxSize = blockSize;
if (thisBlock->IsFreeBlock())
{
UInt32 blockSize = thisBlock->GetBlockHeapUsageSize();
if (blockSize > curMaxSize)
curMaxSize = blockSize;
}
thisBlock = thisBlock->GetNextBlock();
}

Просмотреть файл

@ -128,6 +128,7 @@ class nsLargeHeapAllocator : public nsMemAllocator
virtual nsHeapChunk* AllocateChunk(size_t requestedBlockSize);
virtual void FreeChunk(nsHeapChunk *chunkToFree);
UInt32 GetPaddedBlockSize(UInt32 blockSize) { return ((blockSize + 3) & ~3) + LargeBlockHeader::kLargeBlockOverhead; }
protected:
UInt32 mBaseChunkPercentage;
@ -157,6 +158,8 @@ class nsLargeHeapChunk : public nsHeapChunk
void ReturnBlock(LargeBlockHeader *deadBlock);
UInt32 GetLargestFreeBlock() { return mLargestFreeBlock; }
protected:
void UpdateLargestFreeBlock();

Просмотреть файл

@ -70,16 +70,24 @@ nsMemAllocator::nsMemAllocator(size_t minBlockSize, size_t maxBlockSize)
, mMaxHeapSpaceUsed(0)
, mCurSubheapCount(0)
, mMaxSubheapCount(0)
, mCountHistogram(NULL)
#endif
//--------------------------------------------------------------------
{
#if STATS_MAC_MEMORY
mCountHistogram = (UInt32 *)NewPtrClear(sizeof(UInt32) * (maxBlockSize - minBlockSize + 1));
// failure is ok
#endif
}
//--------------------------------------------------------------------
nsMemAllocator::~nsMemAllocator()
//--------------------------------------------------------------------
{
// free up the subheaps
#if STATS_MAC_MEMORY
if (mCountHistogram)
DisposePtr((Ptr)mCountHistogram);
#endif
}
@ -196,6 +204,10 @@ void nsMemAllocator::AccountForNewBlock(size_t logicalSize)
if (mCurBlockSpaceUsed > mMaxBlockSpaceUsed)
mMaxBlockSpaceUsed = mCurBlockSpaceUsed;
if (mCountHistogram)
{
mCountHistogram[logicalSize - mMinBlockSize]++;
}
}
//--------------------------------------------------------------------
@ -269,6 +281,21 @@ void nsMemAllocator::DumpMemoryStats(PRFileDesc *outFile)
sprintf( outString, "%s of allocated space used: %10.2f\n", "%", 100.0 * mMaxBlockSpaceUsed / mMaxHeapSpaceUsed );
WriteString ( outFile, outString );
if (mCountHistogram)
{
WriteString ( outFile, "\n\n");
WriteString ( outFile, "Block size Total allocations\n------------------------------\n" );
for (UInt32 i = mMinBlockSize; i <= mMaxBlockSize; i ++)
{
sprintf(outString,"%5d %10d\n", i, mCountHistogram[i - mMinBlockSize]);
WriteString ( outFile, outString );
}
WriteString(outFile, "------------------------------\n");
}
WriteString ( outFile, "\n\n");
}

Просмотреть файл

@ -36,6 +36,7 @@ enum {
kFreeBlockTrailerTag = 'free',
kUsedBlockHeaderTag = 'USED',
kUsedBlockTrailerTag = 'used',
kDummyBlockHeaderTag = 'D\'oh',
kRefdBlockHeaderTag = 'REFD',
kRefdBlockTrailerTag = 'refd',
kUsedMemoryFillPattern = 0xDB,
@ -212,6 +213,7 @@ class nsMemAllocator
UInt32 mCurSubheapCount; // current number of subheaps allocated by this allocator
UInt32 mMaxSubheapCount; // max number of subheaps allocated by this allocator
UInt32* mCountHistogram; // cumulative hist of frequencies
// the difference between mCurBlockSpaceUsed and mCurHeapSpaceUsed is
// the allocator overhead, which consists of:

Двоичные данные
lib/mac/MacMemoryAllocator/test/MemoryTest.mcp

Двоичный файл не отображается.