On 09/30/14 03:01, Bernd Edlinger wrote:
Sigh. Yea, I guess if we're hitting the allocator insanely hard,
scrubbing memory might turn out to slow things down in a significant
way. Or it may simply be the case that we're using free'd memory in
some way and with the MALLOC_PERTURB changes we're in an infinite loop
in the dumping code or something similar.
Yeah, that is an interesting thing.
I debugged that, and it turns out, that this is just incredibly slow.
It seems to be in the macro expansion of this construct:
#define t16(x) x x x x x x x x x x x x x x x x
#define M (sizeof (t16(t16(t16(t16(t16(" ")))))) - 1)
libcpp is calling realloc 1.000.000 times for this, resizing
the memory by just one byte at a time. And the worst case of
realloc is O(n), so in the worst case realloc would have
to copy 1/2 * 1.000.000^2 bytes = 500 GB of memory.
With this little change in libcpp, the test suite passed, without any
further regressions:
--- libcpp/charset.c.jj 2014-08-19 07:34:31.000000000 +0200
+++ libcpp/charset.c 2014-09-30 10:45:26.676954120 +0200
@@ -537,6 +537,7 @@ convert_no_conversion (iconv_t cd ATTRIB
if (to->len + flen> to->asize)
{
to->asize = to->len + flen;
+ to->asize *= 2;
to->text = XRESIZEVEC (uchar, to->text, to->asize);
}
memcpy (to->text + to->len, from, flen);
I will prepare a patch for that later.
Thanks for digging into this. We usually try to throttle this growth a
little. Something like this would be consistent with other cases in GCC:
to->asize += to->asize / 4;
Interestingly, if I define MALLOC_CHECK_=3 _and_ MALLOC_PERTURB_
this test passes, even without the above change,
but the test case
gfortran.dg/realloc_on_assign_5.f03 fails in this configuration,
which is a known bug: PR 47674. However it passes when only MALLOC_PERTURB_
is defined.
Weird...
Yea, but that's par for the course when dealing with memory errors.
Jeff