Subject: bug#21556: 25.0.50; Memory leak in emacs -Q with lucid (font)

From: Dmitry Antipov <[email-masked]>
Date: Wed, 30 Sep 2015 13:16:48 +0300

On 09/29/2015 12:28 PM, Dima Kogan wrote:

> I guess I preferred to invest more time. I found and fixed the bug, and
> the patch is attached. The issue was that the compaction code wasn't
> checking all the right lisp objects for the marks. The font entities
> were storing a list of fonts, and this list had to be traversed, looking
> for the marks. See font_clear_cache() for a function that WAS traversing
> the full list.

IMO this code should be reworked to omit 'any_fonts_marked' variable :-),
something like:

diff --git a/src/alloc.c b/src/alloc.c
index 3ab2a6e..3109654 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -5303,8 +5303,25 @@ compact_font_cache_entry (Lisp_Object entry)
              are not marked too.  But we must be sure that nothing is
              marked within OBJ before we really drop it.  */
           for (i = 0; i < size; i++)
-           if (VECTOR_MARKED_P (XFONT_ENTITY (AREF (XCDR (obj), i))))
-             break;
+            {
+              Lisp_Object objlist;
+
+              if (VECTOR_MARKED_P (XFONT_ENTITY (AREF (XCDR (obj), i))))
+                break;
+
+              objlist = AREF (AREF (XCDR (obj), i), FONT_OBJLIST_INDEX);
+              for (; CONSP (objlist); objlist = XCDR (objlist))
+                {
+                  Lisp_Object val = XCAR (objlist);
+                  struct font *font = XFONT_OBJECT (val);
+
+                  if (! NILP (AREF (val, FONT_TYPE_INDEX)) &&
+                      VECTOR_MARKED_P(font))
+                   break;
+                }
+              if (!NILP (objlist))
+                break;
+            }

           if (i == size)
             drop = 1;

In general, this patch hits the case where the font object is marked but the
corresponding font entity is not; but is that legal? IIRC Emacs asks the font
driver to find a font described by font spec, and returned object is a font entity,
which is a list of font objects plus some extra stuff. Thus, there should be
no "free-floating" font objects, i.e. for each font object, there should be
at least one font entity object which references that font. IOW, having
marked font object without marked font entity looks like GC mark bug for me.

Dmitry