Improvements in freelist handling for Memcheck.  See #250065.

(Philippe Waroquiers, philippe.waroquiers@skynet.be)

This patch provides three improvements in the way the free list is 
handled in memcheck.

First improvement: a new command line option --freelist-big-blocks
(default 1000000) specifies the size of "free list big blocks". 
Such big blocks will be put on the free list, but will be re-cycled first
(i.e. in preference to block having a smaller size).
This fixes the bug https://bugs.kde.org/show_bug.cgi?id=250065.
Technically, the freed list is divided in two lists : small
and big blocks. Blocks are first released from the big block list.

Second improvement: the blocks of the freed list are re-cycled before
a new block is malloc-ed, not after a block is freed.
This gives better error messages for dangling pointer errors
when doing many frees without doing malloc between the frees.
(this does not uses more memory).

Third improvement: a block bigger than the free list volume will be
put in the free list (till a malloc is done, so as the needed memory
is not bigger than before) but will be put at the beginning of the
free list, rather than at the end. So, allocating then freeing such a
block does not cause any blocks in the free list to be released.

Results of the improvements above, with the new regression test
memcheck/test/big_blocks_freed_list: with the patch, 7 errors
are detected, 6 are giving the (correct) allocation stack.
Without the patch, only 6 errors are detected, 5 errors without
allocation stack, 1 with a (wrong) allocation stack.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12202 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/memcheck/mc_include.h b/memcheck/mc_include.h
index 597b40f..5279603 100644
--- a/memcheck/mc_include.h
+++ b/memcheck/mc_include.h
@@ -96,7 +96,10 @@
 void MC_(mempool_change)  ( Addr pool, Addr addrA, Addr addrB, SizeT size );
 Bool MC_(mempool_exists)  ( Addr pool );
 
-MC_Chunk* MC_(get_freed_list_head)( void );
+/* Searches for a recently freed block which might bracket Addr a.
+   Return the MC_Chunk* for this block or NULL if no bracketting block
+   is found. */
+MC_Chunk* MC_(get_freed_block_bracketting)( Addr a );
 
 /* For tracking malloc'd blocks.  Nb: it's quite important that it's a
    VgHashTable, because VgHashTable allows duplicate keys without complaint.
@@ -424,6 +427,10 @@
 /* Max volume of the freed blocks queue. */
 extern Long MC_(clo_freelist_vol);
 
+/* Blocks with a size >= MC_(clo_freelist_big_blocks) will be put
+   in the "big block" freed blocks queue. */
+extern Long MC_(clo_freelist_big_blocks);
+
 /* Do leak check at exit?  default: NO */
 extern LeakCheckMode MC_(clo_leak_check);