bool SmallObjAllocator::IsCorrupt( void ) const { if ( NULL == pool_ ) { assert( false ); return true; } if ( 0 == GetAlignment() ) { assert( false ); return true; } if ( 0 == GetMaxObjectSize() ) { assert( false ); return true; } const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() ); for ( std::size_t ii = 0; ii < allocCount; ++ii ) { if ( pool_[ ii ].IsCorrupt() ) return true; } return false; }
void * SmallObjAllocator::Allocate( std::size_t numBytes, bool doThrow ) { if ( numBytes > GetMaxObjectSize() ) return DefaultAllocator( numBytes, doThrow ); assert( NULL != pool_ ); if ( 0 == numBytes ) numBytes = 1; const std::size_t index = GetOffset( numBytes, GetAlignment() ) - 1; const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() ); (void) allocCount; assert( index < allocCount ); FixedAllocator & allocator = pool_[ index ]; assert( allocator.BlockSize() >= numBytes ); assert( allocator.BlockSize() < numBytes + GetAlignment() ); void * place = allocator.Allocate(); if ( ( NULL == place ) && TrimExcessMemory() ) place = allocator.Allocate(); if ( ( NULL == place ) && doThrow ) { #ifdef _MSC_VER throw std::bad_alloc( "could not allocate small object" ); #else // GCC did not like a literal string passed to std::bad_alloc. // so just throw the default-constructed exception. throw std::bad_alloc(); #endif } return place; }
void SmallObjAllocator::Deallocate( void * p ) { if ( NULL == p ) return; assert( NULL != pool_ ); FixedAllocator * pAllocator = NULL; const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() ); Chunk * chunk = NULL; for ( std::size_t ii = 0; ii < allocCount; ++ii ) { chunk = pool_[ ii ].HasBlock( p ); if ( NULL != chunk ) { pAllocator = &pool_[ ii ]; break; } } if ( NULL == pAllocator ) { DefaultDeallocator( p ); return; } assert( NULL != chunk ); const bool found = pAllocator->Deallocate( p, chunk ); (void) found; assert( found ); }
void SmallObjAllocator::Deallocate( void * p, std::size_t numBytes ) { if ( NULL == p ) return; if ( numBytes > GetMaxObjectSize() ) { DefaultDeallocator( p ); return; } assert( NULL != pool_ ); if ( 0 == numBytes ) numBytes = 1; const std::size_t index = GetOffset( numBytes, GetAlignment() ) - 1; const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() ); assert( index < allocCount ); FixedAllocator & allocator = pool_[ index ]; assert( allocator.BlockSize() >= numBytes ); assert( allocator.BlockSize() < numBytes + GetAlignment() ); const bool found = allocator.Deallocate( p, true ); assert( found ); }
bool SmallObjAllocator::TrimExcessMemory( void ) { bool found = false; const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() ); std::size_t i = 0; for ( ; i < allocCount; ++i ) { if ( pool_[ i ].TrimEmptyChunk() ) found = true; } for ( i = 0; i < allocCount; ++i ) { if ( pool_[ i ].TrimChunkList() ) found = true; } return found; }