From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Kenichi Handa Newsgroups: gmane.emacs.bugs 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 Message-ID: References: <49FF3340.2040008@gmx.de> <4A005A64.5050908@gnu.org> <4A3F1B05.7030105@gnu.org> <4A3F7058.902@gnu.org> <4A3F81AC.1070404@gnu.org> <4A420357.8050706@gnu.org> <4A422909.9060800@gnu.org> <4A4379F7.4000100@gnu.org> Reply-To: Kenichi Handa , 3208@emacsbugs.donarmstrong.com NNTP-Posting-Host: lo.gmane.org X-Trace: ger.gmane.org 1245980267 17629 80.91.229.12 (26 Jun 2009 01:37:47 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 26 Jun 2009 01:37:47 +0000 (UTC) Cc: schierlm@gmx.de, 3208@emacsbugs.donarmstrong.com To: Jason Rumney Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Jun 26 03:37:39 2009 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1MK0Nk-0000ap-Sc for geb-bug-gnu-emacs@m.gmane.org; Fri, 26 Jun 2009 03:37:37 +0200 Original-Received: from localhost ([127.0.0.1]:56486 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MK0Nj-0007Kp-V7 for geb-bug-gnu-emacs@m.gmane.org; Thu, 25 Jun 2009 21:37:35 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MK0Nf-0007Ki-3W for bug-gnu-emacs@gnu.org; Thu, 25 Jun 2009 21:37:31 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MK0Na-0007K4-GG for bug-gnu-emacs@gnu.org; Thu, 25 Jun 2009 21:37:30 -0400 Original-Received: from [199.232.76.173] (port=55681 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MK0Na-0007K0-45 for bug-gnu-emacs@gnu.org; Thu, 25 Jun 2009 21:37:26 -0400 Original-Received: from rzlab.ucr.edu ([138.23.92.77]:42249) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MK0NZ-0005OF-IK for bug-gnu-emacs@gnu.org; Thu, 25 Jun 2009 21:37:25 -0400 Original-Received: from rzlab.ucr.edu (rzlab.ucr.edu [127.0.0.1]) by rzlab.ucr.edu (8.14.3/8.14.3/Debian-5) with ESMTP id n5Q1bN3B023285; Thu, 25 Jun 2009 18:37:23 -0700 Original-Received: (from debbugs@localhost) by rzlab.ucr.edu (8.14.3/8.14.3/Submit) id n5Q1U4mp021858; Thu, 25 Jun 2009 18:30:04 -0700 X-Loop: owner@emacsbugs.donarmstrong.com Resent-From: Kenichi Handa Resent-To: bug-submit-list@donarmstrong.com Resent-CC: Emacs Bugs , owner@emacsbugs.donarmstrong.com Resent-Date: Fri, 26 Jun 2009 01:30:04 +0000 Resent-Message-ID: Resent-Sender: owner@emacsbugs.donarmstrong.com X-Emacs-PR-Message: followup 3208 X-Emacs-PR-Package: emacs,w32 X-Emacs-PR-Keywords: Original-Received: via spool by 3208-submit@emacsbugs.donarmstrong.com id=B3208.124597959321732 (code B ref 3208); Fri, 26 Jun 2009 01:30:04 +0000 Original-Received: (at 3208) by emacsbugs.donarmstrong.com; 26 Jun 2009 01:26:33 +0000 X-Spam-Bayes: score:0.5 Bayes not run. spammytokens:Tokens not available. hammytokens:Tokens not available. Original-Received: from mx1.aist.go.jp (mx1.aist.go.jp [150.29.246.133]) by rzlab.ucr.edu (8.14.3/8.14.3/Debian-5) with ESMTP id n5Q1QQJK021712 for <3208@emacsbugs.donarmstrong.com>; Thu, 25 Jun 2009 18:26:27 -0700 Original-Received: from rqsmtp1.aist.go.jp (rqsmtp1.aist.go.jp [150.29.254.115]) by mx1.aist.go.jp with ESMTP id n5Q1QMQs005309; Fri, 26 Jun 2009 10:26:23 +0900 (JST) env-from (handa@m17n.org) Original-Received: from smtp1.aist.go.jp by rqsmtp1.aist.go.jp with ESMTP id n5Q1QMC6026633; Fri, 26 Jun 2009 10:26:22 +0900 (JST) env-from (handa@m17n.org) Original-Received: by smtp1.aist.go.jp with ESMTP id n5Q1QMsT014218; Fri, 26 Jun 2009 10:26:22 +0900 (JST) env-from (handa@m17n.org) Original-Received: from handa by etlken with local (Exim 4.69) (envelope-from ) id 1MK0Cs-0006cp-AB; Fri, 26 Jun 2009 10:26:22 +0900 In-reply-to: <4A4379F7.4000100@gnu.org> (message from Jason Rumney on Thu, 25 Jun 2009 21:21:59 +0800) X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Resent-Date: Thu, 25 Jun 2009 21:37:30 -0400 X-BeenThere: bug-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:28980 Archived-At: In article <4A4379F7.4000100@gnu.org>, Jason Rumney 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 * 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; }