Re-institute SegInfo reference counting and deallocation.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4225 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_aspacemgr/aspacemgr.c b/coregrind/m_aspacemgr/aspacemgr.c
index 250a535..0933775 100644
--- a/coregrind/m_aspacemgr/aspacemgr.c
+++ b/coregrind/m_aspacemgr/aspacemgr.c
@@ -31,7 +31,7 @@
*/
#include "pub_core_basics.h"
-#include "pub_core_debuginfo.h" // Needed for pub_core_aspacemgr :(
+#include "pub_core_debuginfo.h" // Needed for pub_core_aspacemgr.h :(
#include "pub_core_aspacemgr.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
@@ -168,7 +168,7 @@
vg_assert(name);
- if (0) VG_(printf)("alloc_segname %s\n", name);
+ if (0) VG_(printf)("allocate_segname %s\n", name);
len = VG_(strlen)(name);
if (len >= VG_MAX_SEGNAMELEN-1) {
@@ -320,6 +320,8 @@
segments_used++;
}
+// Forward declaration
+static void dealloc_seg_memory(Segment *s);
/* Shift segments [i+1 .. segments_used-1] down by one, and decrement
segments_used.
@@ -328,8 +330,10 @@
{
Int j;
vg_assert(i >= 0 && i < segments_used);
- for (j = i+1; j < segments_used; j++)
- segments[j-1] = segments[j];
+ dealloc_seg_memory(&segments[i]);
+ for (j = i+1; j < segments_used; j++) {
+ segments[j-1] = segments[j];
+ }
segments_used--;
vg_assert(segments_used >= 0 && segments_used < VG_N_SEGMENTS);
}
@@ -434,8 +438,12 @@
vg_assert(a > segments[r].addr);
delta = a - segments[r].addr;
make_space_at(r);
+
segments[r] = segments[r+1];
segments[r].len = delta;
+ if (segments[r].seginfo)
+ VG_(seginfo_incref)(segments[r].seginfo);
+
segments[r+1].len -= delta;
segments[r+1].addr += delta;
segments[r+1].offset += delta;
@@ -527,6 +535,10 @@
s->addr, s->addr+s->len,
s1->addr, s1->addr+s1->len);
s->len += s1->len;
+
+ vg_assert(s->seginfo == s1->seginfo);
+ dealloc_seg_memory(s1);
+
continue;
}
if (wr < rd)
@@ -570,35 +582,15 @@
return (p < se && pe > s->addr);
}
-#if 0
-/* 20050228: apparently unused */
-/* Prepare a Segment structure for recycling by freeing everything
- hanging off it. */
-static void recycleseg(Segment *s)
-{
- if (s->flags & SF_CODE)
- VG_(discard_translations)(s->addr, s->len);
-
- if (s->filename != NULL)
- VG_(arena_free)(VG_AR_CORE, (Char *)s->filename);
-
- /* keep the SegInfo, if any - it probably still applies */
-}
-
/* When freeing a Segment, also clean up every one else's ideas of
what was going on in that range of memory */
-static void freeseg(Segment *s)
+static void dealloc_seg_memory(Segment *s)
{
- recycleseg(s);
if (s->seginfo != NULL) {
VG_(seginfo_decref)(s->seginfo, s->addr);
s->seginfo = NULL;
}
-
- VG_(SkipNode_Free)(&sk_segments, s);
}
-#endif
-
/* Get rid of any translations arising from s. */
/* Note, this is not really the job of the low level memory manager.
@@ -784,7 +776,7 @@
preen_segments();
if (0) show_segments("after map_file_segment");
- /* If this mapping is of the beginning of a file, isn't part of
+ /* If this mapping is at the beginning of a file, isn't part of
Valgrind, is at least readable and seems to contain an object
file, then try reading symbols from it.
@@ -824,21 +816,23 @@
s->seginfo = VG_(read_seg_symbols)(s->addr, s->len, s->offset,
s->filename);
}
- //else
- //if (flags & SF_MMAP) {
- // const SegInfo *info;
- //
- // /* Otherwise see if an existing SegInfo applies to this Segment */
- // for(info = VG_(next_seginfo)(NULL);
- // info != NULL;
- // info = VG_(next_seginfo)(info)) {
- // if (VG_(seg_overlaps)(s, VG_(seg_start)(info), VG_(seg_size)(info)))
- // {
- // s->seginfo = (SegInfo *)info;
- // VG_(seginfo_incref)((SegInfo *)info);
- // }
- // }
- //}
+ else if (flags & SF_MMAP)
+ {
+ const SegInfo *si;
+
+ /* Otherwise see if an existing SegInfo applies to this Segment */
+ for (si = VG_(next_seginfo)(NULL);
+ si != NULL;
+ si = VG_(next_seginfo)(si))
+ {
+ if (VG_(seg_overlaps)(s, VG_(seginfo_start)(si),
+ VG_(seginfo_size)(si)))
+ {
+ s->seginfo = (SegInfo *)si;
+ VG_(seginfo_incref)((SegInfo *)si);
+ }
+ }
+ }
}
/* clean up */