mirror of https://github.com/python/cpython
SF bug 542181: Realloc behavior
The bug report pointed out a bogosity in the comment block explaining thread safety for arena management. Repaired that comment, repaired a couple others while I was at it, and added an assert. _PyMalloc_DebugRealloc: If this needed to get more memory, but couldn't, it erroneously freed the original memory. Repaired that. This is for 2.3 only (unless we decide to backport the new pymalloc).
This commit is contained in:
parent
362ed3451e
commit
52aefc8a7b
|
@ -321,13 +321,14 @@ pymalloc strives at all levels (arena, pool, and block) never to touch a piece
|
||||||
of memory until it's actually needed.
|
of memory until it's actually needed.
|
||||||
|
|
||||||
So long as a pool is in the used state, we're certain there *is* a block
|
So long as a pool is in the used state, we're certain there *is* a block
|
||||||
available for allocating. If pool->freeblock is NULL then, that means we
|
available for allocating, and pool->freeblock is not NULL. If pool->freeblock
|
||||||
simply haven't yet gotten to one of the higher-address blocks. The offset
|
points to the end of the free list before we've carved the entire pool into
|
||||||
from the pool_header to the start of "the next" virgin block is stored in
|
blocks, that means we simply haven't yet gotten to one of the higher-address
|
||||||
the pool_header nextoffset member, and the largest value of nextoffset that
|
blocks. The offset from the pool_header to the start of "the next" virgin
|
||||||
makes sense is stored in the maxnextoffset member when a pool is initialized.
|
block is stored in the pool_header nextoffset member, and the largest value
|
||||||
All the blocks in a pool have been passed out at least once when and only
|
of nextoffset that makes sense is stored in the maxnextoffset member when a
|
||||||
when nextoffset > maxnextoffset.
|
pool is initialized. All the blocks in a pool have been passed out at least
|
||||||
|
once when and only when nextoffset > maxnextoffset.
|
||||||
|
|
||||||
|
|
||||||
Major obscurity: While the usedpools vector is declared to have poolp
|
Major obscurity: While the usedpools vector is declared to have poolp
|
||||||
|
@ -467,8 +468,7 @@ new_arena(void)
|
||||||
maxarenas = 16;
|
maxarenas = 16;
|
||||||
}
|
}
|
||||||
else if (narenas == maxarenas) {
|
else if (narenas == maxarenas) {
|
||||||
/* Grow arenas. Don't use realloc: if this fails, we
|
/* Grow arenas.
|
||||||
* don't want to lose the base addresses we already have.
|
|
||||||
*
|
*
|
||||||
* Exceedingly subtle: Someone may be calling the pymalloc
|
* Exceedingly subtle: Someone may be calling the pymalloc
|
||||||
* free via PyMem_{DEL, Del, FREE, Free} without holding the
|
* free via PyMem_{DEL, Del, FREE, Free} without holding the
|
||||||
|
@ -590,6 +590,7 @@ _PyMalloc_Malloc(size_t nbytes)
|
||||||
*/
|
*/
|
||||||
++pool->ref.count;
|
++pool->ref.count;
|
||||||
bp = pool->freeblock;
|
bp = pool->freeblock;
|
||||||
|
assert(bp != NULL);
|
||||||
if ((pool->freeblock = *(block **)bp) != NULL) {
|
if ((pool->freeblock = *(block **)bp) != NULL) {
|
||||||
UNLOCK();
|
UNLOCK();
|
||||||
return (void *)bp;
|
return (void *)bp;
|
||||||
|
@ -1057,12 +1058,15 @@ _PyMalloc_DebugRealloc(void *p, size_t nbytes)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(nbytes != 0);
|
||||||
/* More memory is needed: get it, copy over the first original_nbytes
|
/* More memory is needed: get it, copy over the first original_nbytes
|
||||||
of the original data, and free the original memory. */
|
of the original data, and free the original memory. */
|
||||||
fresh = _PyMalloc_DebugMalloc(nbytes);
|
fresh = _PyMalloc_DebugMalloc(nbytes);
|
||||||
if (fresh != NULL && original_nbytes > 0)
|
if (fresh != NULL) {
|
||||||
memcpy(fresh, p, original_nbytes);
|
if (original_nbytes > 0)
|
||||||
_PyMalloc_DebugFree(p);
|
memcpy(fresh, p, original_nbytes);
|
||||||
|
_PyMalloc_DebugFree(p);
|
||||||
|
}
|
||||||
return fresh;
|
return fresh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue