From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Chong Yidong Newsgroups: gmane.emacs.bugs Subject: bug#12463: 24.2; pos-visible-in-window-p gets slower over time Date: Fri, 21 Sep 2012 13:42:53 +0800 Message-ID: <878vc4ylr6.fsf@gnu.org> References: <87wqzs1a4c.fsf@queen.i-did-not-set--mail-host-address--so-tickle-me> <83mx0n22p0.fsf@gnu.org> <87d31jcqce.fsf@gnu.org> <4023344.MyoQPQRfcJ@queen> <87sjac1185.fsf@gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1348206217 14341 80.91.229.3 (21 Sep 2012 05:43:37 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 21 Sep 2012 05:43:37 +0000 (UTC) Cc: =?UTF-8?Q?J=C3=B6rg?= Walter , 12463@debbugs.gnu.org To: Juanma Barranquero Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Sep 21 07:43:40 2012 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1TEw1a-00017t-1W for geb-bug-gnu-emacs@m.gmane.org; Fri, 21 Sep 2012 07:43:38 +0200 Original-Received: from localhost ([::1]:51132 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TEw1V-0002uq-Jb for geb-bug-gnu-emacs@m.gmane.org; Fri, 21 Sep 2012 01:43:33 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:58667) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TEw1R-0002tv-OV for bug-gnu-emacs@gnu.org; Fri, 21 Sep 2012 01:43:31 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TEw1P-0002tO-Lw for bug-gnu-emacs@gnu.org; Fri, 21 Sep 2012 01:43:29 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:36462) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TEw1P-0002tK-HO for bug-gnu-emacs@gnu.org; Fri, 21 Sep 2012 01:43:27 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1TEw2w-00076x-Ap for bug-gnu-emacs@gnu.org; Fri, 21 Sep 2012 01:45:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Chong Yidong Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 21 Sep 2012 05:45:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 12463 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 12463-submit@debbugs.gnu.org id=B12463.134820627927291 (code B ref 12463); Fri, 21 Sep 2012 05:45:02 +0000 Original-Received: (at 12463) by debbugs.gnu.org; 21 Sep 2012 05:44:39 +0000 Original-Received: from localhost ([127.0.0.1]:46008 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TEw2Y-000767-Po for submit@debbugs.gnu.org; Fri, 21 Sep 2012 01:44:39 -0400 Original-Received: from mail-pb0-f44.google.com ([209.85.160.44]:53794) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TEw2V-00075u-Ti for 12463@debbugs.gnu.org; Fri, 21 Sep 2012 01:44:38 -0400 Original-Received: by pbbjt11 with SMTP id jt11so4491109pbb.3 for <12463@debbugs.gnu.org>; Thu, 20 Sep 2012 22:42:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-type:content-transfer-encoding; bh=VYUsxVWP5ViigDL6hHTyEx7MFbr0MKpodTO9qzTkAwc=; b=yUf2JSM27A9Jpo4qV1YxaNcZFFcJ5l+Thq+8WoTNh4tE65iTVzw/JtvKbGT7YanChU 9jkqweNnaa4CNmbSiJAZmAEHV8NlBTqoCt/HA29oSmIlKTmm8utdQlR5uNXy9D+mZX7c yKl7JOncnNYypf2NaI6czUERfoENU5rk6/n7BKQ4uX+YHQU1nHEWenN8srvAaOOXQrex rEcfTlsnqjGvPqzCTqSgkoifAnbZPc0tEYDg7XNrztGazOUn7GyB1fVNZJbOCZYAcL9O rlKY2kkL6BJ74zcdpWh2MM9jgV1TC/cn6IMfnEGt9hPmza/VjJpBrLCP2tFYa25+qK6u qvsA== Original-Received: by 10.68.228.98 with SMTP id sh2mr12588244pbc.95.1348206179845; Thu, 20 Sep 2012 22:42:59 -0700 (PDT) Original-Received: from ulysses ([155.69.19.149]) by mx.google.com with ESMTPS id qo8sm4615188pbb.19.2012.09.20.22.42.56 (version=SSLv3 cipher=OTHER); Thu, 20 Sep 2012 22:42:58 -0700 (PDT) In-Reply-To: <87sjac1185.fsf@gnu.org> (Chong Yidong's message of "Fri, 21 Sep 2012 11:52:42 +0800") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2.50 (gnu/linux) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:64673 Archived-At: Chong Yidong writes: >> What kind of duplicate entries image_types had? Were they mostly (or >> all) for pbm/xbm types? > > No, the duplicates were for other image types other than pbm/xbm (in > this case svg). The trouble, as J=C3=B6rg pointed out, is that > define_image_types did not check for the prior existence of an image > type before registering it again. An unfortunate oversight; I've > committed a fix to the trunk. On further inspection of Finit_image_library and friends, the current arrangement seems sub-optimal. We have a Lisp-visible function `init-image-library', which triggers loading of image types. This function is called by lookup_image_type, which afterwards scans the image_types linked list again. Please take a look at the following patch, which moves all the work done by Finit_image_library into lookup_image_type. This requires adding a LIBRARIES argument to lookup_image_type, with the same meaning as Finit_image_library and defaulting to Vdynamic_library_alist. Then Finit_image_library would be a rather simple wrapper around lookup_image_type. Other callers to lookup_image_type, such as redisplay looking up an image, would be unaffected. This patch also gets rid of the CHECK_LIB_AVAILABLE macro and replaces it using a new slot in struct image_type, which stores the initialization function for dynamic loading, if any. This patch is orthogonal to the issue of moving Vlibrary_cache outside w32. One difference in behavior is that it makes the Windows code scan Vlibrary_cache only after it has already failed to look for the image type in image_types, and is about to run the initialization function. I think this is a bit more straightforward. =3D=3D=3D modified file 'src/dispextern.h' *** src/dispextern.h 2012-09-13 02:21:28 +0000 --- src/dispextern.h 2012-09-21 05:15:36 +0000 *************** *** 2766,2771 **** --- 2766,2774 ---- /* Free resources of image IMG which is used on frame F. */ void (* free) (struct frame *f, struct image *img); =20=20 + /* Initialization function, or NULL if none. */ + int (* init) (Lisp_Object); +=20 /* Next in list of all supported image types. */ struct image_type *next; }; =3D=3D=3D modified file 'src/image.c' *** src/image.c 2012-09-21 03:52:23 +0000 --- src/image.c 2012-09-21 05:35:31 +0000 *************** *** 561,568 **** =20=20 /* Function prototypes. */ =20=20 ! static Lisp_Object define_image_type (struct image_type *type, int loaded= ); ! static struct image_type *lookup_image_type (Lisp_Object symbol); static void image_error (const char *format, Lisp_Object, Lisp_Object); static void x_laplace (struct frame *, struct image *); static void x_emboss (struct frame *, struct image *); --- 561,568 ---- =20=20 /* Function prototypes. */ =20=20 ! static struct image_type *define_image_type (struct image_type *, Lisp_Ob= ject); ! static struct image_type *lookup_image_type (Lisp_Object, Lisp_Object); static void image_error (const char *format, Lisp_Object, Lisp_Object); static void x_laplace (struct frame *, struct image *); static void x_emboss (struct frame *, struct image *); *************** *** 581,632 **** /* Define a new image type from TYPE. This adds a copy of TYPE to image_types and caches the loading status of TYPE. */ =20=20 ! static Lisp_Object ! define_image_type (struct image_type *type, int loaded) { ! Lisp_Object success; =20=20 ! if (!loaded) ! success =3D Qnil; ! else { ! struct image_type *p; ! Lisp_Object target_type =3D *(type->type); ! for (p =3D image_types; p; p =3D p->next) ! if (EQ (*(p->type), target_type)) ! return Qt; =20=20 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs. The initialized data segment is read-only. */ p =3D xmalloc (sizeof *p); *p =3D *type; p->next =3D image_types; image_types =3D p; - success =3D Qt; } =20=20 ! CACHE_IMAGE_TYPE (*type->type, success); ! return success; ! } !=20 !=20 ! /* Look up image type SYMBOL, and return a pointer to its image_type ! structure. Value is null if SYMBOL is not a known image type. */ !=20 ! static inline struct image_type * ! lookup_image_type (Lisp_Object symbol) ! { ! struct image_type *type; !=20 ! /* We must initialize the image-type if it hasn't been already. */ ! if (NILP (Finit_image_library (symbol, Vdynamic_library_alist))) ! return 0; /* unimplemented */ !=20 ! for (type =3D image_types; type; type =3D type->next) ! if (EQ (symbol, *type->type)) ! break; !=20 ! return type; } =20=20 =20=20 --- 581,624 ---- /* Define a new image type from TYPE. This adds a copy of TYPE to image_types and caches the loading status of TYPE. */ =20=20 ! static struct image_type * ! define_image_type (struct image_type *type, Lisp_Object libraries) { ! struct image_type *p =3D NULL; ! Lisp_Object target_type =3D *type->type; ! int type_valid =3D 1; !=20 ! for (p =3D image_types; p; p =3D p->next) ! if (EQ (*p->type, target_type)) ! return p; =20=20 ! if (type->init) { ! #ifdef HAVE_NTGUI ! /* If we failed to load the library before, don't try again. */ ! Lisp_Object tested =3D Fassq (target_type, Vlibrary_cache); ! if (CONSP (tested) && NILP (XCDR (tested))) ! type_valid =3D 0; ! else ! #endif ! { ! /* If the load failed, avoid trying again. */ ! type_valid =3D (*type->init)(libraries); ! CACHE_IMAGE_TYPE (target_type, type_valid); ! } ! } =20=20 + if (type_valid) + { /* Make a copy of TYPE to avoid a bus error in a dumped Emacs. The initialized data segment is read-only. */ p =3D xmalloc (sizeof *p); *p =3D *type; p->next =3D image_types; image_types =3D p; } =20=20 ! return p; } =20=20 =20=20 *************** *** 653,659 **** if (CONSP (tem) && SYMBOLP (XCAR (tem))) { struct image_type *type; ! type =3D lookup_image_type (XCAR (tem)); if (type) valid_p =3D type->valid_p (object); } --- 645,651 ---- if (CONSP (tem) && SYMBOLP (XCAR (tem))) { struct image_type *type; ! type =3D lookup_image_type (XCAR (tem), Qnil); if (type) valid_p =3D type->valid_p (object); } *************** *** 986,992 **** =20=20 eassert (valid_image_p (spec)); img->dependencies =3D NILP (file) ? Qnil : list1 (file); ! img->type =3D lookup_image_type (image_spec_value (spec, QCtype, NULL)); eassert (img->type !=3D NULL); img->spec =3D spec; img->lisp_data =3D Qnil; --- 978,984 ---- =20=20 eassert (valid_image_p (spec)); img->dependencies =3D NILP (file) ? Qnil : list1 (file); ! img->type =3D lookup_image_type (image_spec_value (spec, QCtype, NULL),= Qnil); eassert (img->type !=3D NULL); img->spec =3D spec; img->lisp_data =3D Qnil; *************** *** 2262,2267 **** --- 2254,2260 ---- xbm_image_p, xbm_load, x_clear_image, + NULL, NULL }; =20=20 *************** *** 3059,3064 **** --- 3052,3062 ---- xpm_image_p, xpm_load, x_clear_image, + #ifdef HAVE_NTGUI + init_xpm_functions, + #else + NULL, + #endif NULL }; =20=20 *************** *** 4981,4986 **** --- 4979,4985 ---- pbm_image_p, pbm_load, x_clear_image, + NULL, NULL }; =20=20 *************** *** 5395,5400 **** --- 5394,5404 ---- png_image_p, png_load, x_clear_image, + #ifdef HAVE_NTGUI + init_png_functions, + #else + NULL, + #endif NULL }; =20=20 *************** *** 6047,6052 **** --- 6051,6061 ---- jpeg_image_p, jpeg_load, x_clear_image, + #ifdef HAVE_NTGUI + init_jpeg_functions, + #else + NULL, + #endif NULL }; =20=20 *************** *** 6632,6637 **** --- 6641,6651 ---- tiff_image_p, tiff_load, x_clear_image, + #ifdef HAVE_NTGUI + init_tiff_functions, + #else + NULL, + #endif NULL }; =20=20 *************** *** 7080,7085 **** --- 7094,7104 ---- gif_image_p, gif_load, gif_clear_image, + #ifdef HAVE_NTGUI + init_gif_functions, + #else + NULL, + #endif NULL }; =20=20 *************** *** 7571,7576 **** --- 7590,7600 ---- imagemagick_image_p, imagemagick_load, imagemagick_clear_image, + #ifdef HAVE_NTGUI + init_imagemagick_functions, + #else + NULL, + #endif NULL }; =20=20 *************** *** 8123,8128 **** --- 8147,8157 ---- svg_load, /* Handle to function to free sresources for SVG. */ x_clear_image, + #ifdef HAVE_NTGUI + init_svg_functions, + #else + NULL, + #endif /* An internal field to link to the next image type in a list of image types, will be filled in when registering the format. */ NULL *************** *** 8512,8517 **** --- 8541,8551 ---- gs_image_p, gs_load, gs_clear_image, + #ifdef HAVE_NTGUI + init_gs_functions, + #else + NULL, + #endif NULL }; =20=20 *************** *** 8774,8789 **** Initialization ***********************************************************************/ =20=20 - #ifdef HAVE_NTGUI - /* Image types that rely on external libraries are loaded dynamically - if the library is available. */ - #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \ - define_image_type (image_type, init_lib_fn (libraries)) - #else - #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \ - define_image_type (image_type, 1) - #endif /* HAVE_NTGUI */ -=20 DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2,= 2, 0, doc: /* Initialize image library implementing image type TYPE. Return non-nil if TYPE is a supported image type. --- 8808,8813 ---- *************** *** 8793,8853 **** of `dynamic-library-alist', which see). */) (Lisp_Object type, Lisp_Object libraries) { ! #ifdef HAVE_NTGUI ! /* Don't try to reload the library. */ ! Lisp_Object tested =3D Fassq (type, Vlibrary_cache); ! if (CONSP (tested)) ! return XCDR (tested); ! #endif =20=20 /* Types pbm and xbm are built-in and always available. */ ! if (EQ (type, Qpbm) || EQ (type, Qxbm)) ! return Qt; =20=20 #if defined (HAVE_XPM) || defined (HAVE_NS) if (EQ (type, Qxpm)) ! return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries); #endif =20=20 #if defined (HAVE_JPEG) || defined (HAVE_NS) if (EQ (type, Qjpeg)) ! return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, librarie= s); #endif =20=20 #if defined (HAVE_TIFF) || defined (HAVE_NS) if (EQ (type, Qtiff)) ! return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, librarie= s); #endif =20=20 #if defined (HAVE_GIF) || defined (HAVE_NS) if (EQ (type, Qgif)) ! return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries); #endif =20=20 #if defined (HAVE_PNG) || defined (HAVE_NS) if (EQ (type, Qpng)) ! return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries); #endif =20=20 #if defined (HAVE_RSVG) if (EQ (type, Qsvg)) ! return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries); #endif =20=20 #if defined (HAVE_IMAGEMAGICK) if (EQ (type, Qimagemagick)) ! return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_funct= ions, ! libraries); #endif =20=20 #ifdef HAVE_GHOSTSCRIPT if (EQ (type, Qpostscript)) ! return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries); #endif =20=20 ! /* If the type is not recognized, avoid testing it ever again. */ ! CACHE_IMAGE_TYPE (type, Qnil); ! return Qnil; } =20=20 void --- 8817,8883 ---- of `dynamic-library-alist', which see). */) (Lisp_Object type, Lisp_Object libraries) { ! struct image_type *p =3D lookup_image_type (type, libraries); ! return p ? *p->type : Qnil; ! } !=20 ! /* Look up image type SYMBOL, and return a pointer to its image_type ! structure. Value is null if SYMBOL is not a known image type. */ !=20 ! static struct image_type * ! lookup_image_type (Lisp_Object type, Lisp_Object libraries) ! { ! if (NILP (libraries)) ! libraries =3D Vdynamic_library_alist; =20=20 /* Types pbm and xbm are built-in and always available. */ ! if (EQ (type, Qpbm)) ! return &pbm_type; !=20 ! if (EQ (type, Qxbm)) ! return &xbm_type; =20=20 #if defined (HAVE_XPM) || defined (HAVE_NS) if (EQ (type, Qxpm)) ! return define_image_type (&xpm_type, libraries); #endif =20=20 #if defined (HAVE_JPEG) || defined (HAVE_NS) if (EQ (type, Qjpeg)) ! return define_image_type (&jpeg_type, libraries); #endif =20=20 #if defined (HAVE_TIFF) || defined (HAVE_NS) if (EQ (type, Qtiff)) ! return define_image_type (&tiff_type, libraries); #endif =20=20 #if defined (HAVE_GIF) || defined (HAVE_NS) if (EQ (type, Qgif)) ! return define_image_type (&gif_type, libraries); #endif =20=20 #if defined (HAVE_PNG) || defined (HAVE_NS) if (EQ (type, Qpng)) ! return define_image_type (&png_type, libraries); #endif =20=20 #if defined (HAVE_RSVG) if (EQ (type, Qsvg)) ! return define_image_type (&svg_type, libraries); #endif =20=20 #if defined (HAVE_IMAGEMAGICK) if (EQ (type, Qimagemagick)) ! return define_image_type (&imagemagick_type, libraries); #endif =20=20 #ifdef HAVE_GHOSTSCRIPT if (EQ (type, Qpostscript)) ! return define_image_type (&gs_type, libraries); #endif =20=20 ! return NULL; } =20=20 void