mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 20:51:35 +00:00
[zone] Fix z_split_block and Z_Realloc
z_split_block missed updating the back pointer in the block after the split block, and Z_Realloc missed setting the sentinel.
This commit is contained in:
parent
18c0ea3657
commit
82428ffb9d
1 changed files with 28 additions and 4 deletions
|
@ -140,6 +140,7 @@ z_split_block (memblock_t *block, size_t size)
|
|||
.prev = block,
|
||||
.id = ZONEID,
|
||||
};
|
||||
split->next->prev = split;
|
||||
block->next = split;
|
||||
block->block_size = size;
|
||||
return split;
|
||||
|
@ -160,6 +161,12 @@ z_merge_blocks (memzone_t *zone, memblock_t *a, memblock_t *b)
|
|||
return a;
|
||||
}
|
||||
|
||||
static void
|
||||
z_set_sentinal (memblock_t *block)
|
||||
{
|
||||
*(int *) ((byte *) block + block->block_size - 4) = ZONEID;
|
||||
}
|
||||
|
||||
static void
|
||||
z_deadbeef (memblock_t *block)
|
||||
{
|
||||
|
@ -241,6 +248,10 @@ Z_Free (memzone_t *zone, void *ptr)
|
|||
{
|
||||
memblock_t *block, *other;
|
||||
|
||||
if (developer & SYS_zone) {
|
||||
Z_CheckHeap (zone);
|
||||
}
|
||||
|
||||
if (!ptr) {
|
||||
if (zone->error) {
|
||||
zone->error (zone->data, "Z_Free: NULL pointer");
|
||||
|
@ -279,6 +290,9 @@ Z_Free (memzone_t *zone, void *ptr)
|
|||
// merge the next free block onto the end
|
||||
z_merge_blocks (zone, block, other);
|
||||
}
|
||||
if (developer & SYS_zone) {
|
||||
Z_CheckHeap (zone);
|
||||
}
|
||||
}
|
||||
|
||||
VISIBLE void *
|
||||
|
@ -306,7 +320,7 @@ Z_TagMalloc (memzone_t *zone, size_t size, int tag)
|
|||
memblock_t *start, *rover, *base;
|
||||
|
||||
if (developer & SYS_zone) {
|
||||
Z_CheckHeap (zone); // DEBUG
|
||||
Z_CheckHeap (zone);
|
||||
}
|
||||
|
||||
if (!tag) {
|
||||
|
@ -347,7 +361,11 @@ Z_TagMalloc (memzone_t *zone, size_t size, int tag)
|
|||
zone->used += base->block_size;
|
||||
|
||||
// marker for memory trash testing
|
||||
*(int *) ((byte *) base + base->block_size - 4) = ZONEID;
|
||||
z_set_sentinal (base);
|
||||
|
||||
if (developer & SYS_zone) {
|
||||
Z_CheckHeap (zone);
|
||||
}
|
||||
|
||||
return (void *) (base + 1);
|
||||
}
|
||||
|
@ -358,8 +376,9 @@ Z_Realloc (memzone_t *zone, void *ptr, size_t size)
|
|||
if (!ptr)
|
||||
return Z_Malloc (zone, size);
|
||||
|
||||
if (developer & SYS_zone)
|
||||
Z_CheckHeap (zone); // DEBUG
|
||||
if (developer & SYS_zone) {
|
||||
Z_CheckHeap (zone);
|
||||
}
|
||||
|
||||
auto block = z_ptr_block (zone, ptr);
|
||||
if (block->tag == 0) {
|
||||
|
@ -383,12 +402,14 @@ Z_Realloc (memzone_t *zone, void *ptr, size_t size)
|
|||
}
|
||||
}
|
||||
block->size = size;
|
||||
z_set_sentinal (block);
|
||||
} else {
|
||||
auto other = block->next;
|
||||
if (!other->tag && block->block_size + other->block_size >= new_size) {
|
||||
z_split_block (other, new_size - block->block_size);
|
||||
z_merge_blocks (zone, block, other);
|
||||
block->size = size;
|
||||
z_set_sentinal (block);
|
||||
} else {
|
||||
ptr = Z_TagMalloc (zone, size, 1);
|
||||
}
|
||||
|
@ -400,6 +421,9 @@ Z_Realloc (memzone_t *zone, void *ptr, size_t size)
|
|||
}
|
||||
Sys_Error ("Z_Realloc: failed on allocation of %zd bytes", size);
|
||||
}
|
||||
if (developer & SYS_zone) {
|
||||
Z_CheckHeap (zone);
|
||||
}
|
||||
|
||||
if (ptr != old_ptr) {
|
||||
memmove (ptr, old_ptr, min (old_size, size));
|
||||
|
|
Loading…
Reference in a new issue