aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-03-05 16:51:48 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2013-03-05 16:51:48 +0100
commit0b50e6540fe69191c78689d0ff5d0a1e18130391 (patch)
tree621a132b81c013b0cba91140e85a6ab093c5ecd4 /gcc
parent4ccf8f43ce30db2991656165ddd8839598751075 (diff)
downloadgcc-0b50e6540fe69191c78689d0ff5d0a1e18130391.zip
gcc-0b50e6540fe69191c78689d0ff5d0a1e18130391.tar.gz
gcc-0b50e6540fe69191c78689d0ff5d0a1e18130391.tar.bz2
re PR middle-end/56461 (GCC is leaking lots of memory)
PR middle-end/56461 * ggc-common.c (gt_pch_save): For ENABLE_VALGRIND_CHECKING, if VALGRIND_GET_VBITS is defined, temporarily make object memory all defined, and restore previous valgrind addressability and definability afterwards. Free this_object at the end. * c-pch.c (pch_init): Free target_validity at the end. From-SVN: r196469
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/c-family/ChangeLog5
-rw-r--r--gcc/c-family/c-pch.c2
-rw-r--r--gcc/ggc-common.c68
4 files changed, 80 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4734403..4c0744f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,12 @@
2013-03-05 Jakub Jelinek <jakub@redhat.com>
PR middle-end/56461
+ * ggc-common.c (gt_pch_save): For ENABLE_VALGRIND_CHECKING,
+ if VALGRIND_GET_VBITS is defined, temporarily make object
+ memory all defined, and restore previous valgrind addressability
+ and definability afterwards. Free this_object at the end.
+
+ PR middle-end/56461
* lra.c (lra): Call lra_clear_live_ranges if live_p,
right before calling lra_create_live_ranges, also call it
when clearing live_p. Only call lra_clear_live_ranges
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index b8ca5ae..6d90bfb 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,8 @@
+2013-03-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/56461
+ * c-pch.c (pch_init): Free target_validity at the end.
+
2013-03-04 Jakub Jelinek <jakub@redhat.com>
* c-pretty-print.c (pp_c_pretty_printer_init): Clear pp->flags.
diff --git a/gcc/c-family/c-pch.c b/gcc/c-family/c-pch.c
index c40ee8d..7b0eca7 100644
--- a/gcc/c-family/c-pch.c
+++ b/gcc/c-family/c-pch.c
@@ -141,6 +141,8 @@ pch_init (void)
if (pch_ready_to_save_cpp_state)
pch_cpp_save_state ();
+
+ XDELETE (target_validity);
}
/* Whether preprocessor state has been saved in a PCH file. */
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index f02224a..91c8249 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -561,6 +561,10 @@ gt_pch_save (FILE *f)
ggc_pch_prepare_write (state.d, state.f);
+#if defined ENABLE_VALGRIND_CHECKING && defined VALGRIND_GET_VBITS
+ vec<char> vbits = vNULL;
+#endif
+
/* Actually write out the objects. */
for (i = 0; i < state.count; i++)
{
@@ -569,6 +573,50 @@ gt_pch_save (FILE *f)
this_object_size = state.ptrs[i]->size;
this_object = XRESIZEVAR (char, this_object, this_object_size);
}
+#if defined ENABLE_VALGRIND_CHECKING && defined VALGRIND_GET_VBITS
+ /* obj might contain uninitialized bytes, e.g. in the trailing
+ padding of the object. Avoid warnings by making the memory
+ temporarily defined and then restoring previous state. */
+ int get_vbits = 0;
+ size_t valid_size = state.ptrs[i]->size;
+ if (__builtin_expect (RUNNING_ON_VALGRIND, 0))
+ {
+ if (vbits.length () < valid_size)
+ vbits.safe_grow (valid_size);
+ get_vbits = VALGRIND_GET_VBITS (state.ptrs[i]->obj,
+ vbits.address (), valid_size);
+ if (get_vbits == 3)
+ {
+ /* We assume that first part of obj is addressable, and
+ the rest is unaddressable. Find out where the boundary is
+ using binary search. */
+ size_t lo = 0, hi = valid_size;
+ while (hi > lo)
+ {
+ size_t mid = (lo + hi) / 2;
+ get_vbits = VALGRIND_GET_VBITS ((char *) state.ptrs[i]->obj
+ + mid, vbits.address (),
+ 1);
+ if (get_vbits == 3)
+ hi = mid;
+ else if (get_vbits == 1)
+ lo = mid + 1;
+ else
+ break;
+ }
+ if (get_vbits == 1 || get_vbits == 3)
+ {
+ valid_size = lo;
+ get_vbits = VALGRIND_GET_VBITS (state.ptrs[i]->obj,
+ vbits.address (),
+ valid_size);
+ }
+ }
+ if (get_vbits == 1)
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_DEFINED (state.ptrs[i]->obj,
+ state.ptrs[i]->size));
+ }
+#endif
memcpy (this_object, state.ptrs[i]->obj, state.ptrs[i]->size);
if (state.ptrs[i]->reorder_fn != NULL)
state.ptrs[i]->reorder_fn (state.ptrs[i]->obj,
@@ -582,11 +630,29 @@ gt_pch_save (FILE *f)
state.ptrs[i]->note_ptr_fn == gt_pch_p_S);
if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S)
memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size);
+#if defined ENABLE_VALGRIND_CHECKING && defined VALGRIND_GET_VBITS
+ if (__builtin_expect (get_vbits == 1, 0))
+ {
+ (void) VALGRIND_SET_VBITS (state.ptrs[i]->obj, vbits.address (),
+ valid_size);
+ if (valid_size != state.ptrs[i]->size)
+ VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS ((char *)
+ state.ptrs[i]->obj
+ + valid_size,
+ state.ptrs[i]->size
+ - valid_size));
+ }
+#endif
}
+#if defined ENABLE_VALGRIND_CHECKING && defined VALGRIND_GET_VBITS
+ vbits.release ();
+#endif
+
ggc_pch_finish (state.d, state.f);
gt_pch_fixup_stringpool ();
- free (state.ptrs);
+ XDELETE (state.ptrs);
+ XDELETE (this_object);
htab_delete (saving_htab);
}