Message ID | DUB118-W45BE232759802EBFCF73FFE4BB0@phx.gbl |
---|---|
State | New |
Headers | show |
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
--- 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);