diff options
| author | Xiaohong Bao <bao@lindenlab.com> | 2011-01-07 14:57:35 -0700 | 
|---|---|---|
| committer | Xiaohong Bao <bao@lindenlab.com> | 2011-01-07 14:57:35 -0700 | 
| commit | 7daa3d1ca10199468946feef0ce8eb67489deee0 (patch) | |
| tree | e212d4170de2e7d859d8ae855e1aeb2c001880ed | |
| parent | 9434f0c2a0e46c580a2aacc04cc1b58876bd3bd8 (diff) | |
fixed a hash bug, enlarged the overhead for large allocations, and add new chunk to the tail of the linked list so new allocations go to oldest chunks first.
| -rw-r--r-- | indra/llcommon/llmemory.cpp | 46 | ||||
| -rw-r--r-- | indra/llcommon/llmemory.h | 3 | 
2 files changed, 32 insertions, 17 deletions
| diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 1f40f5e17a..543f17baf4 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -393,8 +393,6 @@ LLPrivateMemoryPool::LLMemoryBlock::~LLMemoryBlock()  //create and initialize a memory block  void LLPrivateMemoryPool::LLMemoryBlock::init(char* buffer, U32 buffer_size, U32 slot_size)  { -	llassert_always(buffer_size >= slot_size) ; -  	mBuffer = buffer ;  	mBufferSize = buffer_size ;  	mSlotSize = slot_size ; @@ -590,12 +588,18 @@ void LLPrivateMemoryPool::LLMemoryChunk::init(char* buffer, U32 buffer_size, U32  }  //static  -U32 LLPrivateMemoryPool::LLMemoryChunk::getMaxOverhead(U32 data_buffer_size, U32 min_page_size)  +U32 LLPrivateMemoryPool::LLMemoryChunk::getMaxOverhead(U32 data_buffer_size, U32 min_slot_size,  +													   U32 max_slot_size, U32 min_block_size, U32 max_block_size)  {  	//for large allocations, reserve some extra memory for meta data to avoid wasting much  -	if(data_buffer_size / min_page_size < 64) //large allocations +	if(data_buffer_size / min_slot_size < 64) //large allocations  	{ -		return 4096 ; //4KB +		U32 overhead = sizeof(LLMemoryChunk) + (data_buffer_size / min_block_size) * sizeof(LLMemoryBlock) + +			sizeof(LLMemoryBlock*) * (max_slot_size / min_slot_size) + sizeof(LLMemoryBlock*) * (max_block_size / min_block_size + 1) ; + +		//round to integer times of min_block_size +		overhead = ((overhead + min_block_size - 1) / min_block_size) * min_block_size ; +		return overhead ;  	}  	else  	{ @@ -1290,12 +1294,14 @@ LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_inde  	if(chunk_index < LARGE_ALLOCATION)  	{  		preferred_size = CHUNK_SIZE ; //4MB -		overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_BLOCK_SIZES[chunk_index]) ; +		overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_SLOT_SIZES[chunk_index], +			MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ;  	}  	else  	{  		preferred_size = LARGE_CHUNK_SIZE ; //16MB -		overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_BLOCK_SIZES[chunk_index]) ; +		overhead = LLMemoryChunk::getMaxOverhead(preferred_size, MIN_SLOT_SIZES[chunk_index],  +			MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ;  	}  	checkSize(preferred_size + overhead) ; @@ -1306,20 +1312,28 @@ LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::addChunk(S32 chunk_inde  	{  		return NULL ;  	} -	memset(buffer, 0, preferred_size + overhead) ; - +	  	LLMemoryChunk* chunk = new (buffer) LLMemoryChunk() ;  	chunk->init(buffer, preferred_size + overhead, MIN_SLOT_SIZES[chunk_index],  		MAX_SLOT_SIZES[chunk_index], MIN_BLOCK_SIZES[chunk_index], MAX_BLOCK_SIZES[chunk_index]) ; -	//add to the head of the linked list -	chunk->mNext = mChunkList[chunk_index] ; -	if(mChunkList[chunk_index]) +	//add to the tail of the linked list  	{ -		mChunkList[chunk_index]->mPrev = chunk ; +		if(!mChunkList[chunk_index]) +		{ +			mChunkList[chunk_index] = chunk ; +		} +		else +		{ +			LLMemoryChunk* cur = mChunkList[chunk_index] ; +			while(cur->mNext) +			{ +				cur = cur->mNext ; +			} +			cur->mNext = chunk ; +			chunk->mPrev = cur ; +		}  	} -	chunk->mPrev = NULL ; -	mChunkList[chunk_index] = chunk ;  	//insert into the hash table  	addToHashTable(chunk) ; @@ -1425,7 +1439,7 @@ void LLPrivateMemoryPool::addToHashTable(LLMemoryChunk* chunk)  		{  			llassert_always(mChunkHashList[end_key] != chunk) -			need_rehash =  mChunkHashList[end_key]->mHashNext != NULL ; +			need_rehash =  mChunkHashList[end_key]->mHashNext != NULL || mChunkHashList[end_key] == chunk->mHashNext;  			if(!need_rehash)  			{  				mChunkHashList[end_key]->mHashNext = chunk ; diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index e42dc174b5..5a2889958b 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -142,7 +142,8 @@ public:  		bool containsAddress(const char* addr) const; -		static U32 getMaxOverhead(U32 data_buffer_size, U32 min_page_size) ; +		static U32 getMaxOverhead(U32 data_buffer_size, U32 min_slot_size,  +													   U32 max_slot_size, U32 min_block_size, U32 max_block_size) ;  		void dump() ; | 
