Fix realloc bookkeeping blunder (r=waterson,pnunn, NOT PART OF DEFAULT BUILD).

This commit is contained in:
brendan%mozilla.org 2000-12-12 05:48:16 +00:00
Родитель 475a6cbddc
Коммит 3edfe573ec
2 изменённых файлов: 66 добавлений и 14 удалений

Просмотреть файл

@ -897,21 +897,25 @@ __ptr_t calloc(size_t count, size_t size)
__ptr_t realloc(__ptr_t ptr, size_t size) __ptr_t realloc(__ptr_t ptr, size_t size)
{ {
__ptr_t oldptr;
callsite *oldsite, *site; callsite *oldsite, *site;
size_t oldsize; size_t oldsize;
PLHashNumber hash; PLHashNumber hash;
PLHashEntry *he; PLHashEntry **hep, *he;
allocation *alloc; allocation *alloc;
tmstats.realloc_calls++; tmstats.realloc_calls++;
if (suppress_tracing == 0) { if (suppress_tracing == 0) {
if (tmmon) oldptr = ptr;
PR_EnterMonitor(tmmon);
oldsite = NULL; oldsite = NULL;
oldsize = 0; oldsize = 0;
if (ptr && get_allocations()) { he = NULL;
hash = hash_pointer(ptr); if (tmmon)
he = *PL_HashTableRawLookup(allocations, hash, ptr); PR_EnterMonitor(tmmon);
if (oldptr && get_allocations()) {
hash = hash_pointer(oldptr);
hep = PL_HashTableRawLookup(allocations, hash, oldptr);
he = *hep;
if (he) { if (he) {
oldsite = (callsite*) he->value; oldsite = (callsite*) he->value;
alloc = (allocation*) he; alloc = (allocation*) he;
@ -936,6 +940,11 @@ __ptr_t realloc(__ptr_t ptr, size_t size)
if (tmmon && suppress_tracing == 0) if (tmmon && suppress_tracing == 0)
PR_ExitMonitor(tmmon); PR_ExitMonitor(tmmon);
#endif #endif
/*
* When realloc() fails, the original block is not freed or moved, so
* we'll leave the allocation entry untouched.
*/
} else if (suppress_tracing == 0) { } else if (suppress_tracing == 0) {
#ifdef EXIT_TMMON_AROUND_REALLOC #ifdef EXIT_TMMON_AROUND_REALLOC
if (tmmon) if (tmmon)
@ -948,7 +957,24 @@ __ptr_t realloc(__ptr_t ptr, size_t size)
} }
if (ptr && allocations) { if (ptr && allocations) {
suppress_tracing++; suppress_tracing++;
he = PL_HashTableAdd(allocations, ptr, site); if (ptr != oldptr) {
/*
* If we're reallocating (not allocating new space by passing
* null to realloc) and realloc moved the block, free oldptr.
*/
if (he)
PL_HashTableRawRemove(allocations, hep, he);
/* Record the new allocation now, setting he. */
he = PL_HashTableAdd(allocations, ptr, site);
} else {
/*
* If we haven't yet recorded an allocation (possibly due to a
* temporary memory shortage), do it now.
*/
if (!he)
he = PL_HashTableAdd(allocations, ptr, site);
}
suppress_tracing--; suppress_tracing--;
if (he) { if (he) {
alloc = (allocation*) he; alloc = (allocation*) he;

Просмотреть файл

@ -897,21 +897,25 @@ __ptr_t calloc(size_t count, size_t size)
__ptr_t realloc(__ptr_t ptr, size_t size) __ptr_t realloc(__ptr_t ptr, size_t size)
{ {
__ptr_t oldptr;
callsite *oldsite, *site; callsite *oldsite, *site;
size_t oldsize; size_t oldsize;
PLHashNumber hash; PLHashNumber hash;
PLHashEntry *he; PLHashEntry **hep, *he;
allocation *alloc; allocation *alloc;
tmstats.realloc_calls++; tmstats.realloc_calls++;
if (suppress_tracing == 0) { if (suppress_tracing == 0) {
if (tmmon) oldptr = ptr;
PR_EnterMonitor(tmmon);
oldsite = NULL; oldsite = NULL;
oldsize = 0; oldsize = 0;
if (ptr && get_allocations()) { he = NULL;
hash = hash_pointer(ptr); if (tmmon)
he = *PL_HashTableRawLookup(allocations, hash, ptr); PR_EnterMonitor(tmmon);
if (oldptr && get_allocations()) {
hash = hash_pointer(oldptr);
hep = PL_HashTableRawLookup(allocations, hash, oldptr);
he = *hep;
if (he) { if (he) {
oldsite = (callsite*) he->value; oldsite = (callsite*) he->value;
alloc = (allocation*) he; alloc = (allocation*) he;
@ -936,6 +940,11 @@ __ptr_t realloc(__ptr_t ptr, size_t size)
if (tmmon && suppress_tracing == 0) if (tmmon && suppress_tracing == 0)
PR_ExitMonitor(tmmon); PR_ExitMonitor(tmmon);
#endif #endif
/*
* When realloc() fails, the original block is not freed or moved, so
* we'll leave the allocation entry untouched.
*/
} else if (suppress_tracing == 0) { } else if (suppress_tracing == 0) {
#ifdef EXIT_TMMON_AROUND_REALLOC #ifdef EXIT_TMMON_AROUND_REALLOC
if (tmmon) if (tmmon)
@ -948,7 +957,24 @@ __ptr_t realloc(__ptr_t ptr, size_t size)
} }
if (ptr && allocations) { if (ptr && allocations) {
suppress_tracing++; suppress_tracing++;
he = PL_HashTableAdd(allocations, ptr, site); if (ptr != oldptr) {
/*
* If we're reallocating (not allocating new space by passing
* null to realloc) and realloc moved the block, free oldptr.
*/
if (he)
PL_HashTableRawRemove(allocations, hep, he);
/* Record the new allocation now, setting he. */
he = PL_HashTableAdd(allocations, ptr, site);
} else {
/*
* If we haven't yet recorded an allocation (possibly due to a
* temporary memory shortage), do it now.
*/
if (!he)
he = PL_HashTableAdd(allocations, ptr, site);
}
suppress_tracing--; suppress_tracing--;
if (he) { if (he) {
alloc = (allocation*) he; alloc = (allocation*) he;