bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


From: Dmitry Antipov
Subject: bug#15876: 24.3.50; Highly degraded performance between rev 114715 and 115006
Date: Mon, 02 Dec 2013 14:45:25 +0400
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.1.1

On 12/01/2013 08:31 PM, Eli Zaretskii wrote:

Dmitry, can you please look into this?  I'm not familiar enough with
the font stuff, so I don't see how was the font-spec and its
font-entities stored in the font cache supposed to be referenced from
some other Lisp object, to make sure they are marked and not GC'ed.

It should be easy - just use this:

=== modified file 'src/alloc.c'
--- src/alloc.c 2013-12-01 22:33:13 +0000
+++ src/alloc.c 2013-12-02 09:32:55 +0000
@@ -5731,7 +5731,18 @@
   eassert (!VECTOR_MARKED_P (ptr));
   VECTOR_MARK (ptr);           /* Else mark it.  */
   if (size & PSEUDOVECTOR_FLAG)
-    size &= PSEUDOVECTOR_SIZE_MASK;
+    {
+      size &= PSEUDOVECTOR_SIZE_MASK;
+      if (PSEUDOVECTOR_TYPEP (&ptr->header, PVEC_FONT))
+       {
+         Lisp_Object tmp;
+         XSETFONT (tmp, ptr);
+         if (FONT_SPEC_P (tmp))
+           fprintf (stderr, "mark font-spec\n");
+         else if (FONT_ENTITY_P (tmp))
+           fprintf (stderr, "mark font-entity\n");
+       }
+    }

and set breakpoints to fprintf(). I tried this and see that font-spec
objects can be referenced from face caches:

(gdb) bt 3 full
#0  mark_vectorlike (ptr=0x13178b8) at ../../trunk/src/alloc.c:5741
        tmp = {i = 20019389}
        size = 13
        i = 20019389
#1  0x00000000005ec050 in mark_object (arg=...) at ../../trunk/src/alloc.c:6084
        ptr = 0x13178b8
        pvectype = 15
        obj = {i = 20019384}
        cdr_count = 0
#2  0x00000000005eb92b in mark_face_cache (c=0x15049b0) at 
../../trunk/src/alloc.c:5839
        face = 0x18d2050
        i = 2
        j = 15
(More stack frames follow...)

I.e. (struct face *)0x18d2050 has font-spec object in lface[15].

But the most of font-spec and font-entity objects are referenced via
staticpro'ed globals Vfontset_table and ft_face_cache. For example:

(gdb) bt 16
#0  mark_vectorlike (ptr=0x129a288) at ../../trunk/src/alloc.c:5741
#1  0x00000000005ec050 in mark_object (arg=...) at ../../trunk/src/alloc.c:6084
#2  0x00000000005eb5f0 in mark_vectorlike (ptr=0x1296428) at 
../../trunk/src/alloc.c:5752
#3  0x00000000005ec050 in mark_object (arg=...) at ../../trunk/src/alloc.c:6084
#4  0x00000000005eb5f0 in mark_vectorlike (ptr=0x129a4d0) at 
../../trunk/src/alloc.c:5752
#5  0x00000000005ec050 in mark_object (arg=...) at ../../trunk/src/alloc.c:6084
#6  0x00000000005eb725 in mark_char_table (ptr=0x1788060) at 
../../trunk/src/alloc.c:5779
#7  0x00000000005eb717 in mark_char_table (ptr=0x12094d0) at 
../../trunk/src/alloc.c:5776
#8  0x00000000005eb717 in mark_char_table (ptr=0x13e2578) at 
../../trunk/src/alloc.c:5776
#9  0x00000000005eb717 in mark_char_table (ptr=0xd85188) at 
../../trunk/src/alloc.c:5776
#10 0x00000000005ec02c in mark_object (arg=...) at ../../trunk/src/alloc.c:6069
#11 0x00000000005eb5f0 in mark_vectorlike (ptr=0xd85080) at 
../../trunk/src/alloc.c:5752
#12 0x00000000005ec050 in mark_object (arg=...) at ../../trunk/src/alloc.c:6084
#13 0x00000000005eac4b in Fgarbage_collect () at ../../trunk/src/alloc.c:5489
#14 0x0000000000563500 in maybe_gc () at ../../trunk/src/lisp.h:4462
#15 0x000000000060ec3e in Ffuncall (nargs=2, args=0x7fffffff0790) at 
../../trunk/src/eval.c:2756
(gdb) bt 16 full
...
#13 0x00000000005eac4b in Fgarbage_collect () at ../../trunk/src/alloc.c:5489
        nextb = 0x0
        stack_top_variable = 0 '\000'
        i = 1491
        message_p = false
        count = 140
        start = {tv_sec = 1385977872, tv_nsec = 656653658}
        retval = {i = 13914818}
        tot_before = 0
...
(gdb) p staticvec[1491]
$8 = (Lisp_Object *) 0xd25cb0 <Vfontset_table>

In any case, it seems like they are never marked on Windows, because
if I set a breakpoint in the line marked below:

          /* If font-spec is not marked, most likely all font-entities
             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;

          if (i == size)  <<<<<<<<<<<<<<<<<<<<<
            drop = 1;
        }

with a condition i != size, that breakpoint never breaks.

The best way to hit this breakpoint is to run something like:

(defun bloat-font ()
  (interactive)
  (let ((fonts (x-list-fonts "*")))
    (while fonts
      (condition-case nil (set-frame-font (car fonts)) (error nil))
      (setq fonts (cdr fonts))
      (redisplay))))

(This is X-specific; I believe there should be a similar MS-Windows method).

Subtle "triangle example" works just fine for me (with default font used by
GTK3 build and 'emacs -Q' at least).

Also I'm curious how to reproduce this issue with X. In particular, how to
find a font so "heavy" that an attempt to load it creates a lot of Lisp data
(hundreds Kbytes, enough to reach gc_cons_threshold each time)?

Dmitry






reply via email to

[Prev in Thread] Current Thread [Next in Thread]