all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Kenichi Handa <handa@m17n.org>
To: Jason Rumney <jasonr@gnu.org>
Cc: schierlm@gmx.de, 3208@emacsbugs.donarmstrong.com
Subject: bug#3208: 23.0.93; Memory full / crash when displaying lots of characters from a	large	font (like Arial Unicode or Code2000) which is not explicitly	selected (on Win32)
Date: Fri, 26 Jun 2009 10:26:22 +0900	[thread overview]
Message-ID: <E1MK0Cs-0006cp-AB@etlken> (raw)
In-Reply-To: <4A4379F7.4000100@gnu.org> (message from Jason Rumney on Thu, 25 Jun 2009 21:21:59 +0800)

In article <4A4379F7.4000100@gnu.org>, Jason Rumney <jasonr@gnu.org> writes:

> It seems to avoid the problem in this case at least. I can now insert 
> over a million of the characters from the original recipe without a 
> problem (and within 5 seconds) by changing the 16 in the original recipe 
> to 20.

> I think this change should go in the release branch,

I think we need the previous change too for 23.1.  Yidon and
Stefan, may I install the attached change in EMACS_23_1_RC?
It seems that this is an effective workaround of the serious
problem on Windows.  Theoretically, the same problem happens
on GNU/Linux too.

> then we can close the bug (or lower its priority if you
> would rather continue to investigate).

Please just lower the priority.  I'll continue to
investigate.  I now have one hypothesis.

On Windows, both uniscribe and gdi font backends returns
many fonts.  When Emacs try to find a suitable font from
them, they are concatinated to a single vector and sorted.
This vector is created and abondoned many times.

If no GC happens while displaying all characters of that
long line, those temporarily created Lisp vectors accumulate
in memory without reused, which may lead to memory full.

What do you think?

---
Kenichi Handa
handa@m17n.org


2009-06-25  Kenichi Handa  <handa@m17n.org>

	* fontset.c (fontset_find_font): When a usable rfont_def is found
	in a fallback font-group, make it the first element of the group.
	(fontset_get_font_group): Return 0 if no font-group is set for C.
	(fontset_font): Record the availability of a font for C both in
	the realized fontsets of the current one and the default one.

Index: fontset.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/fontset.c,v
retrieving revision 1.173
diff -u -r1.173 fontset.c
--- fontset.c	8 Jun 2009 04:33:40 -0000	1.173
+++ fontset.c	26 Jun 2009 01:00:46 -0000
@@ -459,6 +459,12 @@
   XSETCAR (font_group, make_number (charset_ordered_list_tick));
 }
 
+/* Return a font-group (actually a cons (-1 . FONT-GROUP-VECTOR)) for
+   character C in FONTSET.  If C is -1, return a fallback font-group.
+   If C is not -1, the value may be Qt (FONTSET doesn't have a font
+   for C even in the fallback group, or 0 (a font for C may be found
+   only in the fallback group).  */
+
 static Lisp_Object
 fontset_get_font_group (Lisp_Object fontset, int c)
 {
@@ -480,9 +486,10 @@
     font_group = FONTSET_FALLBACK (base_fontset);
   if (NILP (font_group))
     {
+      font_group = make_number (0);
       if (c >= 0)
-	char_table_set_range (fontset, from, to, make_number (0));
-      return Qnil;
+	char_table_set_range (fontset, from, to, font_group);
+      return font_group;
     }
   font_group = Fcopy_sequence (font_group);
   for (i = 0; i < ASIZE (font_group); i++)
@@ -524,9 +531,10 @@
      int id, fallback;
 {
   Lisp_Object vec, font_group;
-  int i, charset_matched = -1;
+  int i, charset_matched = -1, found_index;
   FRAME_PTR f = (FRAMEP (FONTSET_FRAME (fontset)))
     ? XFRAME (selected_frame) : XFRAME (FONTSET_FRAME (fontset));
+  Lisp_Object rfont_def;
 
   font_group = fontset_get_font_group (fontset, fallback ? -1 : c);
   if (! CONSP (font_group))
@@ -546,9 +554,9 @@
 	   first.  */
 	for (i = 0; i < ASIZE (vec); i++)
 	  {
-	    Lisp_Object rfont_def = AREF (vec, i);
 	    Lisp_Object repertory;
 
+	    rfont_def = AREF (vec, i);
 	    if (NILP (rfont_def))
 	      break;
 	    repertory = FONT_DEF_REPERTORY (RFONT_DEF_FONT_DEF (rfont_def));
@@ -564,18 +572,22 @@
   /* Find the first available font in the vector of RFONT-DEF.  */
   for (i = 0; i < ASIZE (vec); i++)
     {
-      Lisp_Object rfont_def, font_def;
+      Lisp_Object font_def;
       Lisp_Object font_entity, font_object;
 
       if (i == 0 && charset_matched >= 0)
 	{
 	  /* Try the element matching with the charset ID at first.  */
 	  rfont_def = AREF (vec, charset_matched);
+	  found_index = charset_matched;
 	  charset_matched = -1;
 	  i--;
 	}
       else if (i != charset_matched)
-	rfont_def = AREF (vec, i);
+	{
+	  rfont_def = AREF (vec, i);
+	  found_index = i;
+	}
       else
 	continue;
 
@@ -623,7 +635,7 @@
 	}
 
       if (font_has_char (f, font_object, c))
-	return rfont_def;
+	goto found;
 
       /* Find a font already opened, maching with the current spec,
 	 and supporting C. */
@@ -637,7 +649,7 @@
 	    break;
 	  font_object = RFONT_DEF_OBJECT (AREF (vec, i));
 	  if (! NILP (font_object) && font_has_char (f, font_object, c))
-	    return rfont_def;
+	    goto found;
 	}
 
       /* Find a font-entity with the current spec and supporting C.  */
@@ -654,6 +666,7 @@
 					     Qnil);
 	  if (NILP (font_object))
 	    continue;
+	  found_index = i;
 	  RFONT_DEF_NEW (rfont_def, font_def);
 	  RFONT_DEF_SET_OBJECT (rfont_def, font_object);
 	  RFONT_DEF_SET_SCORE (rfont_def, RFONT_DEF_SCORE (rfont_def));
@@ -661,10 +674,12 @@
 	  for (j = 0; j < i; j++)
 	    ASET (new_vec, j, AREF (vec, j));
 	  ASET (new_vec, j, rfont_def);
+	  found_index = j;
 	  for (j++; j < ASIZE (new_vec); j++)
 	    ASET (new_vec, j, AREF (vec, j - 1));
 	  XSETCDR (font_group, new_vec);
-	  return rfont_def;
+	  vec = new_vec;
+	  goto found;
 	}
 
       /* No font of the current spec for C.  Try the next spec.  */
@@ -673,6 +688,19 @@
 
   FONTSET_SET (fontset, make_number (c), make_number (0));
   return Qnil;
+
+ found:
+  if (fallback && found_index > 0)
+    {
+      /* The order of fonts in the fallback font-group is not that
+	 important, and it is better to move the found font to the
+	 first of the group so that the next try will find it
+	 quickly. */
+      for (i = found_index; i > 0; i--)
+	ASET (vec, i, AREF (vec, i - 1));
+      ASET (vec, 0, rfont_def);
+    }
+  return rfont_def;
 }
 
 
@@ -683,15 +711,15 @@
      struct face *face;
      int id;
 {
-  Lisp_Object rfont_def;
+  Lisp_Object rfont_def, default_rfont_def;
   Lisp_Object base_fontset;
 
   /* Try a font-group of FONTSET. */
   rfont_def = fontset_find_font (fontset, c, face, id, 0);
   if (VECTORP (rfont_def))
     return rfont_def;
-  if (EQ (rfont_def, Qt))
-    goto no_font;
+  if (NILP (rfont_def))
+    FONTSET_SET (fontset, make_number (c), make_number (0));
 
   /* Try a font-group of the default fontset. */
   base_fontset = FONTSET_BASE (fontset);
@@ -700,32 +728,36 @@
       if (NILP (FONTSET_DEFAULT (fontset)))
 	FONTSET_DEFAULT (fontset)
 	  = make_fontset (FONTSET_FRAME (fontset), Qnil, Vdefault_fontset);
-      rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 0);
-      if (VECTORP (rfont_def))
-	return rfont_def;
-      if (EQ (rfont_def, Qt))
-	goto no_font;
+      default_rfont_def
+	= fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 0);
+      if (VECTORP (default_rfont_def))
+	return default_rfont_def;
+      if (NILP (default_rfont_def))
+	FONTSET_SET (FONTSET_DEFAULT (fontset), make_number (c),
+		     make_number (0));
     }
 
   /* Try a fallback font-group of FONTSET. */
-  rfont_def = fontset_find_font (fontset, c, face, id, 1);
-  if (VECTORP (rfont_def))
-    return rfont_def;
-  if (EQ (rfont_def, Qt))
-    goto no_font;
+  if (! EQ (rfont_def, Qt))
+    {
+      rfont_def = fontset_find_font (fontset, c, face, id, 1);
+      if (VECTORP (rfont_def))
+	return rfont_def;
+      /* Remember that FONTSET has no font for C.  */
+      FONTSET_SET (fontset, make_number (c), Qt);
+    }
 
-  /* Try a fallback font-group of the default fontset . */
-  if (! EQ (base_fontset, Vdefault_fontset))
+  /* Try a fallback font-group of the default fontset. */
+  if (! EQ (base_fontset, Vdefault_fontset)
+      && ! EQ (default_rfont_def, Qt))
     {
       rfont_def = fontset_find_font (FONTSET_DEFAULT (fontset), c, face, id, 1);
       if (VECTORP (rfont_def))
 	return rfont_def;
+      /* Remember that the default fontset has no font for C.  */
+      FONTSET_SET (FONTSET_DEFAULT (fontset), make_number (c), Qt);
     }
 
- no_font:
-  /* Remember that we have no font for C.  */
-  FONTSET_SET (fontset, make_number (c), Qt);
-
   return Qnil;
 }
 





  reply	other threads:[~2009-06-26  1:26 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <4AAF9D6C.1040303@gnu.org>
2009-05-04 18:26 ` bug#3208: 23.0.93; Memory full / crash when displaying lots of characters from a large font (like Arial Unicode or Code2000) which is not explicitly selected (on Win32) Michael Schierl
2009-05-05 15:25   ` Jason Rumney
2009-05-05 15:46     ` Jason Rumney
2009-05-19  2:13     ` Kenichi Handa
2009-06-18  5:29       ` Jason Rumney
2009-06-22  5:47       ` Jason Rumney
2009-06-22 11:22         ` Kenichi Handa
2009-06-22 11:51           ` Jason Rumney
2009-06-22 12:51             ` Kenichi Handa
2009-06-22 13:05               ` Jason Rumney
2009-06-22 14:01                 ` bug#3650: M-x gdb unusable on Windows Jason Rumney
2009-06-23  1:59                   ` Kenichi Handa
2009-06-23  3:37                     ` Dan Nicolaescu
2009-06-23  6:22                     ` Nick Roberts
2009-06-23  7:38                       ` Kenichi Handa
2009-06-23  6:09                   ` Nick Roberts
2009-06-23  7:59                     ` Jason Rumney
2009-06-23 13:22                     ` Kenichi Handa
2009-06-23 17:08                       ` Dan Nicolaescu
2009-06-25  5:50                       ` Kenichi Handa
2009-06-25  6:13                         ` Nick Roberts
2009-06-25  7:51                           ` Kenichi Handa
2019-11-02  6:04                   ` Stefan Kangas
2019-11-02  8:41                     ` Eli Zaretskii
2022-04-13  0:40                       ` Lars Ingebrigtsen
2009-06-24  4:26                 ` bug#3208: 23.0.93; Memory full / crash when displaying lots of characters from a large font (like Arial Unicode or Code2000) which is not explicitly selected (on Win32) Kenichi Handa
2009-06-24 10:37                   ` Jason Rumney
2009-06-24 11:45                     ` Kenichi Handa
2009-06-24 10:43                   ` Jason Rumney
2009-06-24 11:55                     ` Kenichi Handa
     [not found]                       ` <4A422909.9060800@gnu.org>
2009-06-25  8:10                         ` Kenichi Handa
2009-06-25 13:21                           ` Jason Rumney
2009-06-26  1:26                             ` Kenichi Handa [this message]
2009-06-26  5:54                               ` Jason Rumney
2009-06-26 13:12                                 ` Kenichi Handa
2009-07-02 12:13                               ` Kenichi Handa
2009-07-02 21:36                                 ` Stefan Monnier
2009-07-03  2:11                                   ` Kenichi Handa
2009-09-15 14:05   ` bug#3208: marked as done (23.0.93; Memory full / crash when displaying lots of characters from a large font (like Arial Unicode or Code2000) which is not explicitly selected (on Win32)) Emacs bug Tracking System
2009-05-06 23:11 bug#3208: 23.0.93; Memory full / crash when displaying lots of characters from a large font (like Arial Unicode or Code2000) which is not explicitly selected (on Win32) Chong Yidong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1MK0Cs-0006cp-AB@etlken \
    --to=handa@m17n.org \
    --cc=3208@emacsbugs.donarmstrong.com \
    --cc=jasonr@gnu.org \
    --cc=schierlm@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.