Merge in the revised client request stuff from 2.4.X. This significantly
reduces the number of memcheck regtest failures we get.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3367 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c
index b074a22..56d07a9 100644
--- a/memcheck/mc_main.c
+++ b/memcheck/mc_main.c
@@ -1618,18 +1618,16 @@
over dead ones. Instead we must use free/inuse flags and scan for
an empty slot at allocation time. This in turn means allocation is
relatively expensive, so we hope this does not happen too often.
-*/
-typedef
- enum { CG_NotInUse, CG_NoAccess, CG_Writable, CG_Readable }
- CGenBlockKind;
+ An unused block has start == size == 0
+*/
typedef
struct {
Addr start;
SizeT size;
ExeContext* where;
- CGenBlockKind kind;
+ Char* desc;
}
CGenBlock;
@@ -1655,7 +1653,7 @@
for (i = 0; i < vg_cgb_used; i++) {
vg_cgb_search++;
- if (vg_cgbs[i].kind == CG_NotInUse)
+ if (vg_cgbs[i].start == 0 && vg_cgbs[i].size == 0)
return i;
}
@@ -1708,7 +1706,7 @@
/* Perhaps it's a general block ? */
for (i = 0; i < vg_cgb_used; i++) {
- if (vg_cgbs[i].kind == CG_NotInUse)
+ if (vg_cgbs[i].start == 0 && vg_cgbs[i].size == 0)
continue;
if (VG_(addr_is_in_block)(a, vg_cgbs[i].start, vg_cgbs[i].size)) {
MAC_Mempool **d, *mp;
@@ -1740,6 +1738,7 @@
ai->blksize = vg_cgbs[i].size;
ai->rwoffset = (Int)(a) - (Int)(vg_cgbs[i].start);
ai->lastchange = vg_cgbs[i].where;
+ ai->desc = vg_cgbs[i].desc;
return True;
}
}
@@ -1789,44 +1788,46 @@
break;
case VG_USERREQ__MAKE_NOACCESS: /* make no access */
- i = vg_alloc_client_block();
- /* VG_(printf)("allocated %d %p\n", i, vg_cgbs); */
- vg_cgbs[i].kind = CG_NoAccess;
- vg_cgbs[i].start = arg[1];
- vg_cgbs[i].size = arg[2];
- vg_cgbs[i].where = VG_(get_ExeContext) ( tid );
mc_make_noaccess ( arg[1], arg[2] );
- *ret = i;
+ *ret = -1;
break;
case VG_USERREQ__MAKE_WRITABLE: /* make writable */
- i = vg_alloc_client_block();
- vg_cgbs[i].kind = CG_Writable;
- vg_cgbs[i].start = arg[1];
- vg_cgbs[i].size = arg[2];
- vg_cgbs[i].where = VG_(get_ExeContext) ( tid );
mc_make_writable ( arg[1], arg[2] );
- *ret = i;
+ *ret = -1;
break;
case VG_USERREQ__MAKE_READABLE: /* make readable */
- i = vg_alloc_client_block();
- vg_cgbs[i].kind = CG_Readable;
- vg_cgbs[i].start = arg[1];
- vg_cgbs[i].size = arg[2];
- vg_cgbs[i].where = VG_(get_ExeContext) ( tid );
mc_make_readable ( arg[1], arg[2] );
- *ret = i;
+ *ret = -1;
break;
+ case VG_USERREQ__CREATE_BLOCK: /* describe a block */
+ if (arg[1] != 0 && arg[2] != 0) {
+ i = vg_alloc_client_block();
+ /* VG_(printf)("allocated %d %p\n", i, vg_cgbs); */
+ vg_cgbs[i].start = arg[1];
+ vg_cgbs[i].size = arg[2];
+ vg_cgbs[i].desc = VG_(strdup)((Char *)arg[3]);
+ vg_cgbs[i].where = VG_(get_ExeContext) ( tid );
+
+ *ret = i;
+ } else
+ *ret = -1;
+ break;
+
case VG_USERREQ__DISCARD: /* discard */
if (vg_cgbs == NULL
- || arg[2] >= vg_cgb_used || vg_cgbs[arg[2]].kind == CG_NotInUse)
- return 1;
- tl_assert(arg[2] >= 0 && arg[2] < vg_cgb_used);
- vg_cgbs[arg[2]].kind = CG_NotInUse;
- vg_cgb_discards++;
- *ret = 0;
+ || arg[2] >= vg_cgb_used ||
+ (vg_cgbs[arg[2]].start == 0 && vg_cgbs[arg[2]].size == 0)) {
+ *ret = 1;
+ } else {
+ tl_assert(arg[2] >= 0 && arg[2] < vg_cgb_used);
+ vg_cgbs[arg[2]].start = vg_cgbs[arg[2]].size = 0;
+ VG_(free)(vg_cgbs[arg[2]].desc);
+ vg_cgb_discards++;
+ *ret = 0;
+ }
break;
case VG_USERREQ__GET_VBITS:
@@ -1858,6 +1859,7 @@
return True;
}
+
/*------------------------------------------------------------*/
/*--- Setup ---*/
/*------------------------------------------------------------*/