Fix Heap class for x86_64

This commit is contained in:
dhewg 2011-12-01 13:50:22 +01:00
parent 506ea7b316
commit 2c26f0c52a

View file

@ -43,9 +43,9 @@ If you have questions concerning this license or the applicable additional terms
//
//===============================================================
#define SMALL_HEADER_SIZE ( (int) ( sizeof( byte ) + sizeof( byte ) ) )
#define MEDIUM_HEADER_SIZE ( (int) ( sizeof( mediumHeapEntry_s ) + sizeof( byte ) ) )
#define LARGE_HEADER_SIZE ( (int) ( sizeof( dword * ) + sizeof( byte ) ) )
#define SMALL_HEADER_SIZE ( (intptr_t) ( sizeof( byte ) + sizeof( byte ) ) )
#define MEDIUM_HEADER_SIZE ( (intptr_t) ( sizeof( mediumHeapEntry_s ) + sizeof( byte ) ) )
#define LARGE_HEADER_SIZE ( (intptr_t) ( sizeof( dword * ) + sizeof( byte ) ) )
#define ALIGN_SIZE( bytes ) ( ( (bytes) + ALIGN - 1 ) & ~(ALIGN - 1) )
#define SMALL_ALIGN( bytes ) ( ALIGN_SIZE( (bytes) + SMALL_HEADER_SIZE ) - SMALL_HEADER_SIZE )
@ -320,24 +320,24 @@ idHeap::Allocate16
void *idHeap::Allocate16( const dword bytes ) {
byte *ptr, *alignedPtr;
ptr = (byte *) malloc( bytes + 16 + 4 );
ptr = (byte *) malloc( bytes + 16 + sizeof(intptr_t) );
if ( !ptr ) {
if ( defragBlock ) {
idLib::common->Printf( "Freeing defragBlock on alloc of %i.\n", bytes );
free( defragBlock );
defragBlock = NULL;
ptr = (byte *) malloc( bytes + 16 + 4 );
ptr = (byte *) malloc( bytes + 16 + sizeof(intptr_t) );
AllocDefragBlock();
}
if ( !ptr ) {
common->FatalError( "malloc failure for %i", bytes );
}
}
alignedPtr = (byte *) ( ( ( (int) ptr ) + 15) & ~15 );
if ( alignedPtr - ptr < 4 ) {
alignedPtr = (byte *) ( ( ( (intptr_t) ptr ) + 15) & ~15 );
if ( alignedPtr - ptr < sizeof(intptr_t) ) {
alignedPtr += 16;
}
*((int *)(alignedPtr - 4)) = (int) ptr;
*((intptr_t *)(alignedPtr - sizeof(intptr_t))) = (intptr_t) ptr;
return (void *) alignedPtr;
}
@ -347,7 +347,7 @@ idHeap::Free16
================
*/
void idHeap::Free16( void *p ) {
free( (void *) *((int *) (( (byte *) p ) - 4)) );
free( (void *) *((intptr_t *) (( (byte *) p ) - sizeof(intptr_t))) );
}
/*
@ -381,7 +381,7 @@ dword idHeap::Msize( void *p ) {
return ((mediumHeapEntry_s *)(((byte *)(p)) - ALIGN_SIZE( MEDIUM_HEADER_SIZE )))->size - ALIGN_SIZE( MEDIUM_HEADER_SIZE );
}
case LARGE_ALLOC: {
return ((idHeap::page_s*)(*((dword *)(((byte *)p) - ALIGN_SIZE( LARGE_HEADER_SIZE )))))->dataSize - ALIGN_SIZE( LARGE_HEADER_SIZE );
return ((idHeap::page_s*)(*((intptr_t *)(((byte *)p) - ALIGN_SIZE( LARGE_HEADER_SIZE )))))->dataSize - ALIGN_SIZE( LARGE_HEADER_SIZE );
}
default: {
idLib::common->FatalError( "idHeap::Msize: invalid memory block (%s)", idLib::sys->GetCallStackCurStr( 4 ) );
@ -489,7 +489,7 @@ idHeap::page_s* idHeap::AllocatePage( dword bytes ) {
}
}
p->data = (void *) ALIGN_SIZE( (int)((byte *)(p)) + sizeof( idHeap::page_s ) );
p->data = (void *) ALIGN_SIZE( (intptr_t)((byte *)(p)) + sizeof( idHeap::page_s ) );
p->dataSize = size - sizeof(idHeap::page_s);
p->firstFree = NULL;
p->largestFree = 0;
@ -542,8 +542,8 @@ idHeap::SmallAllocate
*/
void *idHeap::SmallAllocate( dword bytes ) {
// we need the at least sizeof( dword ) bytes for the free list
if ( bytes < sizeof( dword ) ) {
bytes = sizeof( dword );
if ( bytes < sizeof( intptr_t ) ) {
bytes = sizeof( intptr_t );
}
// increase the number of bytes if necessary to make sure the next small allocation is aligned
@ -551,13 +551,13 @@ void *idHeap::SmallAllocate( dword bytes ) {
byte *smallBlock = (byte *)(smallFirstFree[bytes / ALIGN]);
if ( smallBlock ) {
dword *link = (dword *)(smallBlock + SMALL_HEADER_SIZE);
intptr_t *link = (intptr_t *)(smallBlock + SMALL_HEADER_SIZE);
smallBlock[1] = SMALL_ALLOC; // allocation identifier
smallFirstFree[bytes / ALIGN] = (void *)(*link);
return (void *)(link);
}
dword bytesLeft = (long)(pageSize) - smallCurPageOffset;
dword bytesLeft = (size_t)(pageSize) - smallCurPageOffset;
// if we need to allocate a new page
if ( bytes >= bytesLeft ) {
@ -590,7 +590,7 @@ void idHeap::SmallFree( void *ptr ) {
((byte *)(ptr))[-1] = INVALID_ALLOC;
byte *d = ( (byte *)ptr ) - SMALL_HEADER_SIZE;
dword *dt = (dword *)ptr;
intptr_t *link = (intptr_t *)ptr;
// index into the table with free small memory blocks
dword ix = *d;
@ -599,7 +599,7 @@ void idHeap::SmallFree( void *ptr ) {
idLib::common->FatalError( "SmallFree: invalid memory block" );
}
*dt = (dword)smallFirstFree[ix]; // write next index
*link = (intptr_t)smallFirstFree[ix]; // write next index
smallFirstFree[ix] = (void *)d; // link
}
@ -929,8 +929,8 @@ void *idHeap::LargeAllocate( dword bytes ) {
}
byte * d = (byte*)(p->data) + ALIGN_SIZE( LARGE_HEADER_SIZE );
dword * dw = (dword*)(d - ALIGN_SIZE( LARGE_HEADER_SIZE ));
dw[0] = (dword)p; // write pointer back to page table
intptr_t * dw = (intptr_t*)(d - ALIGN_SIZE( LARGE_HEADER_SIZE ));
dw[0] = (intptr_t)p; // write pointer back to page table
d[-1] = LARGE_ALLOC; // allocation identifier
// link to 'large used page list'
@ -958,7 +958,7 @@ void idHeap::LargeFree( void *ptr) {
((byte *)(ptr))[-1] = INVALID_ALLOC;
// get page pointer
pg = (idHeap::page_s *)(*((dword *)(((byte *)ptr) - ALIGN_SIZE( LARGE_HEADER_SIZE ))));
pg = (idHeap::page_s *)(*((intptr_t *)(((byte *)ptr) - ALIGN_SIZE( LARGE_HEADER_SIZE ))));
// unlink from doubly linked list
if ( pg->prev ) {
@ -1116,7 +1116,7 @@ void *Mem_Alloc16( const int size ) {
}
void *mem = mem_heap->Allocate16( size );
// make sure the memory is 16 byte aligned
assert( ( ((int)mem) & 15) == 0 );
assert( ( ((intptr_t)mem) & 15) == 0 );
return mem;
}
@ -1137,7 +1137,7 @@ void Mem_Free16( void *ptr ) {
return;
}
// make sure the memory is 16 byte aligned
assert( ( ((int)ptr) & 15) == 0 );
assert( ( ((intptr_t)ptr) & 15) == 0 );
mem_heap->Free16( ptr );
}