Subject: bug#15876: 24.3.50; Highly degraded performance between rev 114715 and 115006

From: Eli Zaretskii <[email-masked]>
Date: Tue, 03 Dec 2013 15:16:34 +0200

> Date: Tue, 03 Dec 2013 13:57:01 +0400
> From: Dmitry Antipov <[email-masked]>
> CC: [email-masked], [email-masked]
> 
> On 12/02/2013 09:52 PM, Eli Zaretskii wrote:
> 
>  > Thanks.  But I think I didn't make myself clear: the issue is not just
>  > to see ANY font-spec objects being marked.  The issue is with those
>  > font-spec objects that are recorded in the font caches that are
>  > compacted by compact_font_caches.  I don't see any code that makes
>  > sure some Lisp object references those caches.  Without that, they
>  > cannot be possibly marked, and will be GC'ed, right?
> 
> Yes, but this is somewhat similar to markers.  All markers are chained
> via 'next' pointers into per-buffer lists, but there is no guarantee that
> _each_ marker is referenced in some other way.  Instead, the marker _may_
> be referenced from some other object.  If this is so, the marker is live.
> Otherwise it's dead.

OK, but the difference is that a buffer is a Lisp object that is
examined by GC, and so its marker list is examined.  Where's something
similar for the font caches?

> But Vfontset_table should present on MS-Windows too, isn't it?

It is present, but how is it related to the issue at hand?

>  > Anyway, I think we are mis-communicating again: the above Lisp code
>  > will cause the breakpoint to fire with i == size, i.e. we will remove
>  > the font-entities from the cache.  I wanted the opposite: to see at
>  > least 1 font-entity that is NOT removed.  So my breakpoint condition
>  > was "i != size", which means we will NOT drop the font-entity.  What I
>  > saw is that this condition is never true, which means we remove ALL of
>  > the font-entities from the cache.
> 
> I understand the problem, but (as of r115362) I'm able to hit the breakpoint
> on the 'break' statement before 'if (i == size)' and found marked font-entity:
> 
> ...
> Breakpoint 1, compact_font_cache_entry (entry=...) at ../../trunk/src/alloc.c:5327
> 5327		      break;
> (gdb) bt 4
> #0  compact_font_cache_entry (entry=...) at ../../trunk/src/alloc.c:5327
> #1  0x00000000005ea772 in compact_font_caches () at ../../trunk/src/alloc.c:5357
> #2  0x00000000005ead99 in Fgarbage_collect () at ../../trunk/src/alloc.c:5531
> #3  0x00000000005635d8 in maybe_gc () at ../../trunk/src/lisp.h:4462
> (More stack frames follow...)
> (gdb) p i
> $1 = 0
> (gdb) p size
> $2 = 4
> (gdb) p XFONT_ENTITY (AREF (XCDR (obj), i))
> $3 = (struct font_entity *) 0x12fd578
> (gdb) p /x XFONT_ENTITY (AREF (XCDR (obj), i))->header.size & ARRAY_MARK_FLAG
> $4 = 0x8000000000000000	      ;;; non-zero ==> mark bit is set
> ...
> 
> Since this font-entity is marked, the whole cache entry is not removed.

This never happened to me on Windows.