Subject: Re: bug#77961: 31.0.50; Rendering HTML email is very slow since commit #eab14d68b2e72b9a6b8b0cc67c9667c2bfbed4f5

From: Eli Zaretskii <[email-masked]>
Date: Tue, 22 Apr 2025 16:19:01 +0300

> From: Gerd Möllmann <[email-masked]>
> Cc: [email-masked],  [email-masked],  [email-masked]
> Date: Tue, 22 Apr 2025 15:04:59 +0200
> 
> Eli Zaretskii <[email-masked]> writes:
> 
> >> +	      if (dim.width > matrix->matrix_w || new_rows)
> >> +		{
> >> +		  row->glyphs[LEFT_MARGIN_AREA]
> >> +		    = xnrealloc (row->glyphs[LEFT_MARGIN_AREA],
> >> +				 dim.width, sizeof (struct glyph));
> >> +		  /* We actually need to clear only the 'frame' member, but
> >> +		     it's easier to clear everything.  */
> >> +		  memset (row->glyphs[LEFT_MARGIN_AREA], 0,
> >> +			  dim.width * sizeof (struct glyph));
> >> +		}
> >
> > This means a very large matrix will not be downsized when possible.
> > Is that a good idea?  Maybe try replacing '>' with '!=' and see if it
> > also solves the problem?
> 
> It's at least what I originally intended when I wrote that function. On
> the grounds that if it grew to some size once, it woiuld likely again to
> that size again. Compare the allocation of the row vector where I did
> the same, for the same reason.
> 
> dispnew.c:
>   416   /* Enlarge MATRIX->rows if necessary.  New rows are cleared.  */
>   417   if (matrix->rows_allocated < dim.height)
>   418     {
>   419       int old_alloc = matrix->rows_allocated;
>   420       new_rows = dim.height - matrix->rows_allocated;
>   421       matrix->rows = xpalloc (matrix->rows, &matrix->rows_allocated,
>   422                               new_rows, INT_MAX, sizeof *matrix->rows);
>   423       memset (matrix->rows + old_alloc, 0,
>   424               (matrix->rows_allocated - old_alloc)
>   425                 * sizeof *matrix->rows);
>   426     }
>   427   else
>   428     new_rows = 0;

So if the user drags the right side of the frame to make it very wide,
or just toggles it full-screen, we will grow the glyph matrices and
never free that space, ever, for as long as the Emacs session lives?
With today's large screens that could be a significant waste of memory
that is never returned to the system, I think?

If the problem we want to avoid is reallocating when the size doesn't
change (which was what happened in this case), then just '!=' should
prevent it, while simultaneously letting us free some memory when the
window is down-sized.  Whether such a realloc actually frees memory is
up to the implementation, but why not let it do what it supposedly
does best?