Subject: Re: bug#12463: 24.2; pos-visible-in-window-p gets slower over time

From: Jörg Walter <[email-masked]>
Date: Tue, 18 Sep 2012 18:18:56 +0200

Op den Dingsdag, de 18. September 2012 Klock 23:17:53 hett Chong Yidong 
schreven:
> Eli Zaretskii <[email-masked]> writes:
> > Can anyone else reproduce this?
> 
> I can reproduce this.  On bisecting, the problem first shows up with
> 
>   revno: 104186
>   fixes bug: http://debbugs.gnu.org/8640
>   committer: Juanma Barranquero <[email-masked]>
>   branch nick: trunk
>   timestamp: Tue 2011-05-10 12:31:33 +0200
>   message:
>   src/image.c (Finit_image_library): Return t for built-in image types.
> 
> A quick glance at the diff of this revision does not reveal immediately
> why it causes the problem, though.

I have no idea why that revision triggers the bug either, but here is a patch 
that fixes the problem. I have no idea if it matches your quality standards, 
but I think it is clean enough. I've reused and adapted some code already 
present for Win32 (which is the reason they don't suffer the same problem).

The linked list `image_types' grows without bounds because 
CHECK_LIB_AVAILABLE/define_image_type never checked if the given image type is 
already in `image_types'. My lisp code triggered tons of `Finit_image_library' 
calls. Since the list is searched linearly at some point, that explains the 
run-time impact.

I have no idea what was originally supposed to ensure `image_types' doesn't 
include duplicate entries, so the patch may be way off... hope someone actually 
knows what is suppsed to go on there.

-- 
CU
	Jörg

--- image.c	2012-09-18 18:10:21.952695267 +0200
+++ image.c.new	2012-09-18 18:09:18.173692841 +0200
@@ -575,12 +575,11 @@
 static void x_emboss (struct frame *, struct image *);
 static int x_build_heuristic_mask (struct frame *, struct image *,
 				   Lisp_Object);
-#ifdef HAVE_NTGUI
+
+static Lisp_Object loaded_image_types;
+
 #define CACHE_IMAGE_TYPE(type, status) \
-  do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0)
-#else
-#define CACHE_IMAGE_TYPE(type, status)
-#endif
+  do { loaded_image_types = Fcons (Fcons (type, status), loaded_image_types); } while (0)
 
 #define ADD_IMAGE_TYPE(type) \
   do { Vimage_types = Fcons (type, Vimage_types); } while (0)
@@ -8743,12 +8742,10 @@
 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 = Fassq (type, Vlibrary_cache);
+  Lisp_Object tested = Fassq (type, loaded_image_types);
   if (CONSP (tested))
     return XCDR (tested);
-#endif
 
   /* Types pbm and xbm are built-in and always available.  */
   if (EQ (type, Qpbm) || EQ (type, Qxbm))
@@ -8828,6 +8825,9 @@
 non-numeric, there is no explicit limit on the size of images.  */);
   Vmax_image_size = make_float (MAX_IMAGE_SIZE);
 
+  loaded_image_types = Qnil;
+  staticpro(&loaded_image_types);
+
   DEFSYM (Qpbm, "pbm");
   ADD_IMAGE_TYPE (Qpbm);