diff options
author | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-03-12 19:39:18 +0000 |
---|---|---|
committer | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-03-12 19:39:18 +0000 |
commit | 580a987ea50fb573468c9e064d00f346f2536e59 (patch) | |
tree | d4a81d532fdfe68b48f123648e9937d1fdd711e2 /gcc/ggc-common.c | |
parent | f973caaeb1e021bbd053d9d5ecf51f33604c6b2c (diff) | |
parent | 803e7ca18954941216d02b8f46f6b9349ab0d778 (diff) | |
download | gcc-580a987ea50fb573468c9e064d00f346f2536e59.tar.gz |
Merged revisions 196444-196445,196448-196472,196474,196478-196480,196483-196491,196493,196495-196500,196504,196506-196508,196511-196513,196516-196520,196523,196525,196527,196531-196532,196536,196538-196540,196542,196544-196552,196554,196557,196559,196562-196564,196567,196570,196572,196575-196576,196579-196581,196587-196592,196595,196597-196598,196600,196602-196604 via svnmerge from
svn+ssh://gcc.gnu.org/svn/gcc/trunk
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/cxx-conversion@196619 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ggc-common.c')
-rw-r--r-- | gcc/ggc-common.c | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index 8ce457dfafa..0bb2eb19f23 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -562,6 +562,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++) { @@ -570,6 +574,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, @@ -583,11 +631,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); saving_htab.dispose (); } |