|
From: <sv...@va...> - 2009-06-24 08:32:53
|
Author: njn
Date: 2009-06-24 09:32:42 +0100 (Wed, 24 Jun 2009)
New Revision: 10374
Log:
In VG_(get_changed_segments) use dynamic memory allocation rather than
static memory allocation to avoid hardwiring an upper limit on CSS_SIZE.
Modified:
trunk/coregrind/m_aspacemgr/aspacemgr-linux.c
trunk/coregrind/m_syswrap/syswrap-darwin.c
trunk/coregrind/pub_core_aspacemgr.h
Modified: trunk/coregrind/m_aspacemgr/aspacemgr-linux.c
===================================================================
--- trunk/coregrind/m_aspacemgr/aspacemgr-linux.c 2009-06-24 08:32:07 UTC (rev 10373)
+++ trunk/coregrind/m_aspacemgr/aspacemgr-linux.c 2009-06-24 08:32:42 UTC (rev 10374)
@@ -3342,6 +3342,7 @@
(*record_gap)(last, (Addr)-1 - last);
}
+Bool css_overflowed;
ChangedSeg* css_local;
Int css_size_local;
Int css_used_local;
@@ -3376,15 +3377,16 @@
else if (nsegments[i].kind == SkFree || nsegments[i].kind == SkResvn) {
/* Add mapping for SkResvn regions */
ChangedSeg* cs = &css_local[css_used_local];
- // If this assert fails, the css_size arg passed to
- // VG_(get_changed_segments) needs to be increased.
- aspacem_assert(css_used_local < css_size_local);
- cs->is_added = True;
- cs->start = addr;
- cs->end = addr + len - 1;
- cs->prot = prot;
- cs->offset = offset;
- css_used_local++;
+ if (css_used_local < css_size_local) {
+ cs->is_added = True;
+ cs->start = addr;
+ cs->end = addr + len - 1;
+ cs->prot = prot;
+ cs->offset = offset;
+ css_used_local++;
+ } else {
+ css_overflowed = True;
+ }
return;
} else if (nsegments[i].kind == SkAnonC ||
@@ -3437,22 +3439,24 @@
if (nsegments[i].kind != SkFree && nsegments[i].kind != SkResvn) {
// V has a mapping, kernel doesn't
ChangedSeg* cs = &css_local[css_used_local];
- // If this assert fails, the css_size arg passed to
- // VG_(get_changed_segments) needs to be increased.
- aspacem_assert(css_used_local < css_size_local);
- cs->is_added = False;
- cs->start = nsegments[i].start;
- cs->end = nsegments[i].end;
- cs->prot = 0;
- cs->offset = 0;
- css_used_local++;
+ if (css_used_local < css_size_local) {
+ cs->is_added = False;
+ cs->start = nsegments[i].start;
+ cs->end = nsegments[i].end;
+ cs->prot = 0;
+ cs->offset = 0;
+ css_used_local++;
+ } else {
+ css_overflowed = True;
+ }
return;
}
}
}
-void VG_(get_changed_segments)(
+// Returns False if 'css' wasn't big enough.
+Bool VG_(get_changed_segments)(
const HChar* when, const HChar* where, /*OUT*/ChangedSeg* css,
Int css_size, /*OUT*/Int* css_used)
{
@@ -3465,6 +3469,7 @@
stats_synccalls++, stats_machcalls, when, where
);
+ css_overflowed = False;
css_local = css;
css_size_local = css_size;
css_used_local = 0;
@@ -3473,6 +3478,12 @@
parse_procselfmaps(&add_mapping_callback, &remove_mapping_callback);
*css_used = css_used_local;
+
+ if (css_overflowed) {
+ aspacem_assert(css_used_local == css_size_local);
+ }
+
+ return !css_overflowed;
}
#endif // HAVE_PROC
Modified: trunk/coregrind/m_syswrap/syswrap-darwin.c
===================================================================
--- trunk/coregrind/m_syswrap/syswrap-darwin.c 2009-06-24 08:32:07 UTC (rev 10373)
+++ trunk/coregrind/m_syswrap/syswrap-darwin.c 2009-06-24 08:32:42 UTC (rev 10374)
@@ -595,17 +595,26 @@
static void sync_mappings(const HChar *when, const HChar *where, Int num)
{
// Usually the number of segments added/removed in a single calls is very
- // small e.g. 1. But the limit was 20 at one point, and that wasn't enough
- // for at least one invocation of Firefox. If we need to go much bigger,
- // should probably make VG_(get_changed_segments) fail if the size isn't
- // big enough, and repeatedly redo it with progressively bigger dynamically
- // allocated buffers until it succeeds.
- #define CSS_SIZE 100
- ChangedSeg css[CSS_SIZE];
- Int css_used;
- Int i;
+ // small e.g. 1. But it sometimes gets up to at least 100 or so (eg. for
+ // Quicktime). So we use a repeat-with-bigger-buffers-until-success model,
+ // because we can't do dynamic allocation within VG_(get_changed_segments),
+ // because it's in m_aspacemgr.
+ ChangedSeg* css = NULL;
+ Int css_size;
+ Int css_used;
+ Int i;
+ Bool ok;
- VG_(get_changed_segments)(when, where, css, CSS_SIZE, &css_used);
+ // 16 is enough for most cases, but small enough that overflow happens
+ // occasionally and thus the overflow path gets some test coverage.
+ css_size = 16;
+ ok = False;
+ while (!ok) {
+ VG_(free)(css); // css is NULL on first iteration; that's ok.
+ css = VG_(malloc)("sys_wrap.sync_mappings", css_size*sizeof(ChangedSeg));
+ ok = VG_(get_changed_segments)(when, where, css, css_size, &css_used);
+ css_size *= 2;
+ }
// Now add/remove them.
for (i = 0; i < css_used; i++) {
@@ -629,6 +638,8 @@
action, cs->start, cs->end + 1, where, when);
}
}
+
+ VG_(free)(css);
}
/* ---------------------------------------------------------------------
Modified: trunk/coregrind/pub_core_aspacemgr.h
===================================================================
--- trunk/coregrind/pub_core_aspacemgr.h 2009-06-24 08:32:07 UTC (rev 10373)
+++ trunk/coregrind/pub_core_aspacemgr.h 2009-06-24 08:32:42 UTC (rev 10374)
@@ -413,7 +413,7 @@
}
ChangedSeg;
-extern void VG_(get_changed_segments)(
+extern Bool VG_(get_changed_segments)(
const HChar* when, const HChar* where, /*OUT*/ChangedSeg* css,
Int css_size, /*OUT*/Int* css_used);
#endif
|