summaryrefslogtreecommitdiff
path: root/gcc/ggc-common.c
diff options
context:
space:
mode:
authordnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2013-03-12 19:39:18 +0000
committerdnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>2013-03-12 19:39:18 +0000
commit580a987ea50fb573468c9e064d00f346f2536e59 (patch)
treed4a81d532fdfe68b48f123648e9937d1fdd711e2 /gcc/ggc-common.c
parentf973caaeb1e021bbd053d9d5ecf51f33604c6b2c (diff)
parent803e7ca18954941216d02b8f46f6b9349ab0d778 (diff)
downloadgcc-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.c68
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 ();
}