PATCH 21.5
It looks like, back in the mists of time, somebody wrote some redisplay
code that leaks Dynarrs, and everybody who created a new redisplay-***.c
since then copied the leaky code. In each of the redisplay-***.c files,
in the *_output_display_block function, the Dynarr named buf gets
initialized when buf is declared. But if there is nothing to do, the
function returns almost immediately, without freeing buf. This patch
moves the creation of the Dynarr past the point where the function can
return early. I also nuked the calls to Dynarr_reset, because they do
nothing when applied to a freshly created Dynarr.
A 21.4 version of the patches I've applied recently is forthcoming. It
will include this leak fix as well.
src/ChangeLog addition:
2006-06-22 Jerry James <james(a)xemacs.org>
* redisplay-gtk.c (gtk_output_display_block): Fix a Dynarr leak.
Don't create the buffer if there is nothing to do.
* redisplay-msw.c (mswindows_output_display_block): Ditto.
* redisplay-output.c (redisplay_output_layout): Ditto.
* redisplay-tty.c (tty_output_display_block): Ditto.
* redisplay-x.c (x_output_display_block): Ditto.
xemacs-21.5 source patch:
Diff command: cvs -q diff -uN
Files affected: src/redisplay-x.c src/redisplay-tty.c src/redisplay-output.c
src/redisplay-msw.c src/redisplay-gtk.c
Index: src/redisplay-gtk.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/redisplay-gtk.c,v
retrieving revision 1.18
diff -d -u -r1.18 redisplay-gtk.c
--- src/redisplay-gtk.c 2005/11/22 11:24:45 1.18
+++ src/redisplay-gtk.c 2006/06/22 22:45:37
@@ -293,7 +293,7 @@
int cursor_width, int cursor_height)
{
struct frame *f = XFRAME (w->frame);
- Ichar_dynarr *buf = Dynarr_new (Ichar);
+ Ichar_dynarr *buf;
Lisp_Object window;
struct display_block *db = Dynarr_atp (dl->display_blocks, block);
@@ -325,7 +325,7 @@
if (end < 0)
end = Dynarr_length (rba);
- Dynarr_reset (buf);
+ buf = Dynarr_new (Ichar);
while (elt < end)
{
Index: src/redisplay-msw.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/redisplay-msw.c,v
retrieving revision 1.42
diff -d -u -r1.42 redisplay-msw.c
--- src/redisplay-msw.c 2005/01/24 23:34:07 1.42
+++ src/redisplay-msw.c 2006/06/22 22:45:37
@@ -907,7 +907,7 @@
int cursor_width, int cursor_height)
{
struct frame *f = XFRAME (w->frame);
- Ichar_dynarr *buf = Dynarr_new (Ichar);
+ Ichar_dynarr *buf;
Lisp_Object window;
struct display_block *db = Dynarr_atp (dl->display_blocks, block);
@@ -934,7 +934,7 @@
if (end < 0)
end = Dynarr_length (rba);
- Dynarr_reset (buf);
+ buf = Dynarr_new (Ichar);
while (elt < end)
{
Index: src/redisplay-output.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/redisplay-output.c,v
retrieving revision 1.26
diff -d -u -r1.26 redisplay-output.c
--- src/redisplay-output.c 2005/01/24 23:34:07 1.26
+++ src/redisplay-output.c 2006/06/22 22:45:37
@@ -1407,7 +1407,7 @@
{
Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
Lisp_Object rest, window = DOMAIN_WINDOW (domain);
- Ichar_dynarr *buf = Dynarr_new (Ichar);
+ Ichar_dynarr *buf;
struct window *w = XWINDOW (window);
struct device *d = DOMAIN_XDEVICE (domain);
int layout_height, layout_width;
@@ -1423,6 +1423,8 @@
/* This makes the glyph area fit into the display area. */
if (!redisplay_normalize_glyph_area (db, dga))
return;
+
+ buf = Dynarr_new (Ichar);
/* Highly dodgy optimization. We want to only output the whole
layout if we really have to. */
Index: src/redisplay-tty.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/redisplay-tty.c,v
retrieving revision 1.25
diff -d -u -r1.25 redisplay-tty.c
--- src/redisplay-tty.c 2005/01/24 23:34:07 1.25
+++ src/redisplay-tty.c 2006/06/22 22:45:37
@@ -206,7 +206,7 @@
int UNUSED (cursor_height))
{
struct frame *f = XFRAME (w->frame);
- Ichar_dynarr *buf = Dynarr_new (Ichar);
+ Ichar_dynarr *buf;
struct display_block *db = Dynarr_atp (dl->display_blocks, block);
rune_dynarr *rba = db->runes;
@@ -232,7 +232,7 @@
if (end < 0)
end = Dynarr_length (rba);
- Dynarr_reset (buf);
+ buf = Dynarr_new (Ichar);
while (elt < end && Dynarr_atp (rba, elt)->xpos < start_pixpos)
{
Index: src/redisplay-x.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/redisplay-x.c,v
retrieving revision 1.42
diff -d -u -r1.42 redisplay-x.c
--- src/redisplay-x.c 2006/06/03 17:50:55 1.42
+++ src/redisplay-x.c 2006/06/22 22:45:38
@@ -432,7 +432,7 @@
#ifndef USE_XFT
struct frame *f = XFRAME (w->frame);
#endif
- Ichar_dynarr *buf = Dynarr_new (Ichar);
+ Ichar_dynarr *buf;
Lisp_Object window;
struct display_block *db = Dynarr_atp (dl->display_blocks, block);
@@ -459,7 +459,7 @@
if (end < 0)
end = Dynarr_length (rba);
- Dynarr_reset (buf);
+ buf = Dynarr_new (Ichar);
while (elt < end)
{
--
Jerry James, Assistant Professor james(a)xemacs.org
Computer Science Department
http://www.cs.usu.edu/~jerry/
Utah State University