зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
2613d8a8bd
Коммит
c7d952aa91
|
@ -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
Двоичные данные
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
Двоичные данные
lib/mac/MacMemoryAllocator/test/MemoryTest.mcp
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче