mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
Make sure we commit enough memory in a new subheap.
This commit is contained in:
parent
5cfe17702e
commit
bf69803ce3
1 changed files with 13 additions and 5 deletions
|
@ -33,16 +33,16 @@ DEFAULT_DEBUG_CHANNEL(heap);
|
||||||
typedef struct tagARENA_INUSE
|
typedef struct tagARENA_INUSE
|
||||||
{
|
{
|
||||||
DWORD size; /* Block size; must be the first field */
|
DWORD size; /* Block size; must be the first field */
|
||||||
WORD threadId; /* Allocating thread id */
|
|
||||||
WORD magic; /* Magic number */
|
WORD magic; /* Magic number */
|
||||||
|
WORD threadId; /* Allocating thread id */
|
||||||
void *callerEIP; /* EIP of caller upon allocation */
|
void *callerEIP; /* EIP of caller upon allocation */
|
||||||
} ARENA_INUSE;
|
} ARENA_INUSE;
|
||||||
|
|
||||||
typedef struct tagARENA_FREE
|
typedef struct tagARENA_FREE
|
||||||
{
|
{
|
||||||
DWORD size; /* Block size; must be the first field */
|
DWORD size; /* Block size; must be the first field */
|
||||||
WORD threadId; /* Freeing thread id */
|
|
||||||
WORD magic; /* Magic number */
|
WORD magic; /* Magic number */
|
||||||
|
WORD threadId; /* Freeing thread id */
|
||||||
struct tagARENA_FREE *next; /* Next free arena */
|
struct tagARENA_FREE *next; /* Next free arena */
|
||||||
struct tagARENA_FREE *prev; /* Prev free arena */
|
struct tagARENA_FREE *prev; /* Prev free arena */
|
||||||
} ARENA_FREE;
|
} ARENA_FREE;
|
||||||
|
@ -446,7 +446,8 @@ static void HEAP_ShrinkBlock(SUBHEAP *subheap, ARENA_INUSE *pArena, DWORD size)
|
||||||
{
|
{
|
||||||
HEAP_CreateFreeBlock( subheap, (char *)(pArena + 1) + size,
|
HEAP_CreateFreeBlock( subheap, (char *)(pArena + 1) + size,
|
||||||
(pArena->size & ARENA_SIZE_MASK) - size );
|
(pArena->size & ARENA_SIZE_MASK) - size );
|
||||||
pArena->size = (pArena->size & ~ARENA_SIZE_MASK) | size;
|
/* assign size plus previous arena flags */
|
||||||
|
pArena->size = size | (pArena->size & ~ARENA_SIZE_MASK);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -636,7 +637,12 @@ static ARENA_FREE *HEAP_FindFreeBlock( HEAP *heap, DWORD size,
|
||||||
(DWORD)heap, size );
|
(DWORD)heap, size );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
size += sizeof(SUBHEAP) + sizeof(ARENA_FREE);
|
/* make sure that we have a big enough size *committed* to fit another
|
||||||
|
* last free arena in !
|
||||||
|
* So just one heap struct, one first free arena which will eventually
|
||||||
|
* get inuse, and HEAP_MIN_BLOCK_SIZE for the second free arena that
|
||||||
|
* might get assigned all remaining free space in HEAP_ShrinkBlock() */
|
||||||
|
size += sizeof(SUBHEAP) + sizeof(ARENA_FREE) + HEAP_MIN_BLOCK_SIZE;
|
||||||
if (!(subheap = HEAP_CreateSubHeap( heap, heap->flags, size,
|
if (!(subheap = HEAP_CreateSubHeap( heap, heap->flags, size,
|
||||||
max( HEAP_DEF_SIZE, size ) )))
|
max( HEAP_DEF_SIZE, size ) )))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -721,6 +727,8 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
|
||||||
if (!(pArena->prev->size & ARENA_FLAG_FREE) ||
|
if (!(pArena->prev->size & ARENA_FLAG_FREE) ||
|
||||||
(pArena->prev->magic != ARENA_FREE_MAGIC))
|
(pArena->prev->magic != ARENA_FREE_MAGIC))
|
||||||
{
|
{
|
||||||
|
/* this often means that the prev arena got overwritten
|
||||||
|
* by a memory write before that prev arena */
|
||||||
ERR("Heap %08lx: prev arena %08lx invalid for %08lx\n",
|
ERR("Heap %08lx: prev arena %08lx invalid for %08lx\n",
|
||||||
(DWORD)subheap->heap, (DWORD)pArena->prev, (DWORD)pArena );
|
(DWORD)subheap->heap, (DWORD)pArena->prev, (DWORD)pArena );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1102,10 +1110,10 @@ LPVOID WINAPI HeapAlloc(
|
||||||
if (!heapPtr) return NULL;
|
if (!heapPtr) return NULL;
|
||||||
flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY;
|
flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY;
|
||||||
flags |= heapPtr->flags;
|
flags |= heapPtr->flags;
|
||||||
if (!(flags & HEAP_NO_SERIALIZE)) EnterCriticalSection( &heapPtr->critSection );
|
|
||||||
size = (size + 3) & ~3;
|
size = (size + 3) & ~3;
|
||||||
if (size < HEAP_MIN_BLOCK_SIZE) size = HEAP_MIN_BLOCK_SIZE;
|
if (size < HEAP_MIN_BLOCK_SIZE) size = HEAP_MIN_BLOCK_SIZE;
|
||||||
|
|
||||||
|
if (!(flags & HEAP_NO_SERIALIZE)) EnterCriticalSection( &heapPtr->critSection );
|
||||||
/* Locate a suitable free block */
|
/* Locate a suitable free block */
|
||||||
|
|
||||||
if (!(pArena = HEAP_FindFreeBlock( heapPtr, size, &subheap )))
|
if (!(pArena = HEAP_FindFreeBlock( heapPtr, size, &subheap )))
|
||||||
|
|
Loading…
Reference in a new issue