diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-03-05 16:51:48 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-03-05 16:51:48 +0100 |
commit | 0b50e6540fe69191c78689d0ff5d0a1e18130391 (patch) | |
tree | 621a132b81c013b0cba91140e85a6ab093c5ecd4 /gcc | |
parent | 4ccf8f43ce30db2991656165ddd8839598751075 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-family/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c-family/c-pch.c | 2 | ||||
-rw-r--r-- | gcc/ggc-common.c | 68 |
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); } |