|
From: <sv...@va...> - 2005-08-11 02:10:12
|
Author: njn
Date: 2005-08-11 03:09:25 +0100 (Thu, 11 Aug 2005)
New Revision: 4380
Log:
Streamline handling of realloc() in Memcheck and Massif by using
the newly added VgHashTable functions. Also some other minor changes.
Modified:
trunk/massif/ms_main.c
trunk/memcheck/mac_malloc_wrappers.c
Modified: trunk/massif/ms_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/massif/ms_main.c 2005-08-11 00:47:10 UTC (rev 4379)
+++ trunk/massif/ms_main.c 2005-08-11 02:09:25 UTC (rev 4380)
@@ -724,7 +724,7 @@
static __inline__
void die_block ( void* p, Bool custom_free )
{
- HP_Chunk *hc, **remove_handle;
+ HP_Chunk *hc;
=20
VGP_PUSHCC(VgpCliMalloc);
=20
@@ -732,11 +732,11 @@
n_frees++;
=20
// Remove HP_Chunk from malloclist
- hc =3D get_HP_Chunk( p, &remove_handle );
- if (hc =3D=3D NULL)
- return; // must have been a bogus free(), or p=3D=3DNULL
- tl_assert(hc->data =3D=3D (Addr)p);
- remove_HP_Chunk(hc, remove_handle);
+ hc =3D (HP_Chunk*)VG_(HT_remove)(malloc_list, (UWord)p);
+ if (NULL =3D=3D hc)
+ return; // must have been a bogus free()
+ tl_assert(n_heap_blocks > 0);
+ n_heap_blocks--;
=20
if (clo_heap && hc->size !=3D 0)
update_XCon(hc->where, -hc->size);
@@ -796,22 +796,20 @@
=20
static void* ms_realloc ( ThreadId tid, void* p_old, SizeT new_size )
{
- HP_Chunk* hc;
- HP_Chunk** remove_handle;
- void* p_new;
- SizeT old_size;
- XPt *old_where, *new_where;
+ HP_Chunk* hc;
+ void* p_new;
+ SizeT old_size;
+ XPt *old_where, *new_where;
=20
VGP_PUSHCC(VgpCliMalloc);
=20
// First try and find the block.
- hc =3D get_HP_Chunk ( p_old, &remove_handle );
+ hc =3D (HP_Chunk*)VG_(HT_remove)(malloc_list, (UWord)p_old);
if (hc =3D=3D NULL) {
VGP_POPCC(VgpCliMalloc);
- return NULL; // must have been a bogus free()
+ return NULL; // must have been a bogus realloc()
}
=20
- tl_assert(hc->data =3D=3D (Addr)p_old);
old_size =3D hc->size;
=20
if (new_size <=3D old_size) {
@@ -839,12 +837,12 @@
if (0 !=3D new_size) update_XCon(new_where, new_size);
}
=20
- // If block has moved, have to remove and reinsert in the malloclist
- // (since the updated 'data' field is the hash lookup key).
- if (p_new !=3D p_old) {
- remove_HP_Chunk(hc, remove_handle);
- add_HP_Chunk(hc);
- }
+ // Now insert the new hc (with a possibly new 'data' field) into
+ // malloc_list. If this realloc() did not increase the memory size, =
we
+ // will have removed and then re-added mc unnecessarily. But that's =
ok
+ // because shrinking a block with realloc() is (presumably) much rare=
r
+ // than growing it, and this way simplifies the growing case.
+ VG_(HT_add_node)(malloc_list, (VgHashNode*)hc);
=20
VGP_POPCC(VgpCliMalloc);
return p_new;
Modified: trunk/memcheck/mac_malloc_wrappers.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/memcheck/mac_malloc_wrappers.c 2005-08-11 00:47:10 UTC (rev 437=
9)
+++ trunk/memcheck/mac_malloc_wrappers.c 2005-08-11 02:09:25 UTC (rev 438=
0)
@@ -84,7 +84,7 @@
some of the oldest blocks in the queue at the same time. */
static void add_to_freed_queue ( MAC_Chunk* mc )
{
- MAC_Chunk* sc1;
+ MAC_Chunk* mc1;
=20
/* Put it at the end of the freed list */
if (freed_list_end =3D=3D NULL) {
@@ -106,21 +106,21 @@
tl_assert(freed_list_start !=3D NULL);
tl_assert(freed_list_end !=3D NULL);
=20
- sc1 =3D freed_list_start;
- freed_list_volume -=3D sc1->size;
+ mc1 =3D freed_list_start;
+ freed_list_volume -=3D mc1->size;
/* VG_(printf)("volume now %d\n", freed_list_volume); */
tl_assert(freed_list_volume >=3D 0);
=20
if (freed_list_start =3D=3D freed_list_end) {
freed_list_start =3D freed_list_end =3D NULL;
} else {
- freed_list_start =3D sc1->next;
+ freed_list_start =3D mc1->next;
}
- sc1->next =3D NULL; /* just paranoia */
+ mc1->next =3D NULL; /* just paranoia */
=20
/* free MAC_Chunk */
- VG_(cli_free) ( (void*)(sc1->data) );
- VG_(free) ( sc1 );
+ VG_(cli_free) ( (void*)(mc1->data) );
+ VG_(free) ( mc1 );
}
}
=20
@@ -141,12 +141,10 @@
=20
/* Allocate its shadow chunk, put it on the appropriate list. */
static
-void add_MAC_Chunk ( ThreadId tid,
- Addr p, SizeT size, MAC_AllocKind kind, VgHashTable=
table)
+MAC_Chunk* create_MAC_Chunk ( ThreadId tid, Addr p, SizeT size,
+ MAC_AllocKind kind)
{
- MAC_Chunk* mc;
-
- mc =3D VG_(malloc)(sizeof(MAC_Chunk));
+ MAC_Chunk* mc =3D VG_(malloc)(sizeof(MAC_Chunk));
mc->data =3D p;
mc->size =3D size;
mc->allockind =3D kind;
@@ -158,10 +156,9 @@
VG_(malloc) should be noaccess as far as the client is
concerned. */
if (!MAC_(check_noaccess)( (Addr)mc, sizeof(MAC_Chunk), NULL )) {
- VG_(tool_panic)("add_MAC_Chunk: shadow area is accessible");
+ VG_(tool_panic)("create_MAC_Chunk: shadow area is accessible");
}=20
-
- VG_(HT_add_node)( table, (VgHashNode*)mc );
+ return mc;
}
=20
/*------------------------------------------------------------*/
@@ -215,7 +212,8 @@
// Only update this stat if allocation succeeded.
cmalloc_bs_mallocd +=3D size;
=20
- add_MAC_Chunk( tid, p, size, kind, table );
+ VG_(HT_add_node)( table,=20
+ (VgHashNode*)create_MAC_Chunk(tid, p, size, kind) )=
;
=20
MAC_(ban_mem_heap)( p-rzB, rzB );
MAC_(new_mem_heap)( p, size, is_zeroed );
@@ -303,7 +301,7 @@
__inline__
void MAC_(handle_free) ( ThreadId tid, Addr p, UInt rzB, MAC_AllocKind k=
ind )
{
- MAC_Chunk* mc;
+ MAC_Chunk* mc;
=20
VGP_PUSHCC(VgpCliMalloc);
=20
@@ -344,10 +342,11 @@
tid, (Addr)p, MAC_MALLOC_REDZONE_SZB, MAC_AllocNewVec);
}
=20
-void* MAC_(realloc) ( ThreadId tid, void* p, SizeT new_size )
+void* MAC_(realloc) ( ThreadId tid, void* p_old, SizeT new_size )
{
- MAC_Chunk* mc;
- MAC_Chunk** prev_chunks_next_ptr;
+ MAC_Chunk* mc;
+ void* p_new;
+ SizeT old_size;
=20
VGP_PUSHCC(VgpCliMalloc);
=20
@@ -358,72 +357,70 @@
if (complain_about_silly_args(new_size, "realloc"))=20
return NULL;
=20
- /* First try and find the block. */
- mc =3D (MAC_Chunk*)VG_(HT_get_node) ( MAC_(malloc_list), (UWord)p,
- (void*)&prev_chunks_next_ptr );
-
+ /* Remove the old block */
+ mc =3D (MAC_Chunk*)VG_(HT_remove) ( MAC_(malloc_list), (UWord)p_old )=
;
if (mc =3D=3D NULL) {
- MAC_(record_free_error) ( tid, (Addr)p );
+ MAC_(record_free_error) ( tid, (Addr)p_old );
/* Perhaps we should return to the program regardless. */
VGP_POPCC(VgpCliMalloc);
return NULL;
}
- =20
+
/* check if its a matching free() / delete / delete [] */
if (MAC_AllocMalloc !=3D mc->allockind) {
/* can not realloc a range that was allocated with new or new [] *=
/
- MAC_(record_freemismatch_error) ( tid, (Addr)p, mc );
+ MAC_(record_freemismatch_error) ( tid, (Addr)p_old, mc );
/* but keep going anyway */
}
=20
- if (mc->size =3D=3D new_size) {
+ old_size =3D mc->size;
+
+ if (old_size =3D=3D new_size) {
/* size unchanged */
mc->where =3D VG_(record_ExeContext)(tid);
- VGP_POPCC(VgpCliMalloc);
- return p;
+ p_new =3D p_old;
=20
- } else if (mc->size > new_size) {
+ } else if (old_size > new_size) {
/* new size is smaller */
MAC_(die_mem_heap)( mc->data+new_size, mc->size-new_size );
mc->size =3D new_size;
mc->where =3D VG_(record_ExeContext)(tid);
- VGP_POPCC(VgpCliMalloc);
- return p;
+ p_new =3D p_old;
=20
} else {
/* new size is bigger */
- Addr p_new;
-
/* Get new memory */
- p_new =3D (Addr)VG_(cli_malloc)(VG_(clo_alignment), new_size);
+ Addr a_new =3D (Addr)VG_(cli_malloc)(VG_(clo_alignment), new_size)=
;
=20
- /* First half kept and copied, second half new,=20
- red zones as normal */
- MAC_(ban_mem_heap) ( p_new-MAC_MALLOC_REDZONE_SZB, MAC_MALLOC_REDZ=
ONE_SZB );
- MAC_(copy_mem_heap)( (Addr)p, p_new, mc->size );
- MAC_(new_mem_heap) ( p_new+mc->size, new_size-mc->size, /*inited*/=
False );
- MAC_(ban_mem_heap) ( p_new+new_size, MAC_MALLOC_REDZONE_SZB );
+ /* First half kept and copied, second half new, red zones as norma=
l */
+ MAC_(ban_mem_heap) ( a_new-MAC_MALLOC_REDZONE_SZB, MAC_MALLOC_REDZ=
ONE_SZB );
+ MAC_(copy_mem_heap)( (Addr)p_old, a_new, mc->size );
+ MAC_(new_mem_heap) ( a_new+mc->size, new_size-mc->size, /*init'd*/=
False );
+ MAC_(ban_mem_heap) ( a_new+new_size, MAC_MALLOC_REDZONE_SZB );
=20
/* Copy from old to new */
- VG_(memcpy)((void*)p_new, p, mc->size);
+ VG_(memcpy)((void*)a_new, p_old, mc->size);
=20
/* Free old memory */
- /* Remove mc from the malloclist using prev_chunks_next_ptr to
- avoid repeating the hash table lookup. Can't remove until at l=
east
- after free_mismatch errors are done because they use
- describe_addr() which looks for it in malloclist. */
- *prev_chunks_next_ptr =3D mc->next;
+ /* Nb: we have to allocate a new MAC_Chunk for the new memory rath=
er
+ than recycling the old one, so that any erroneous accesses to t=
he
+ old memory are reported. */
die_and_free_mem ( tid, mc, MAC_MALLOC_REDZONE_SZB );
=20
- /* this has to be after die_and_free_mem, otherwise the
- former succeeds in shorting out the new block, not the
- old, in the case when both are on the same list. */
- add_MAC_Chunk ( tid, p_new, new_size,=20
- MAC_AllocMalloc, MAC_(malloc_list) );
-
- VGP_POPCC(VgpCliMalloc);
- return (void*)p_new;
+ // Allocate a new chunk.
+ mc =3D create_MAC_Chunk( tid, a_new, new_size, MAC_AllocMalloc );
+ p_new =3D (void*)a_new;
} =20
+
+ // Now insert the new mc (with a possibly new 'data' field) into
+ // malloc_list. If this realloc() did not increase the memory size, =
we
+ // will have removed and then re-added mc unnecessarily. But that's =
ok
+ // because shrinking a block with realloc() is (presumably) much rare=
r
+ // than growing it, and this way simplifies the growing case.
+ VG_(HT_add_node)( MAC_(malloc_list), (VgHashNode*)mc );
+
+ VGP_POPCC(VgpCliMalloc);
+ return p_new;
}
=20
/* Memory pool stuff. */
|