emacs-devel
[Top][All Lists]
Advanced

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

Re: X performance suffers under emacs 21.1.1


From: Gerd Moellmann
Subject: Re: X performance suffers under emacs 21.1.1
Date: 01 Dec 2001 15:24:10 +0100
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.1.50

Richard Stallman <address@hidden> writes:

>       Or maybe one
>     could implement another idea: record where the image was displayed,
>     and remove images from the cache when the buffer they were displayed
>     in is killed
> 
> That seems like a good idea.

Here's another idea that's more precise than just acting when buffers
are killed: one could remove images when their Lisp specs are
unreferenced, like in a weak hash table.  That, maybe combined with a
delay of some sort for the remote case (time and/or # of redisplays,
or whatever) should work pretty well, I think.

Code compiles and is untested; but I'm pretty sure it works.  Daniel,
could you please give it a try?  It's a diff against the current CVS
version, but there's a good chance it can be applied to other versions
as well.

*** alloc.c     2001/12/01 13:57:22     1.255
--- alloc.c     2001/12/01 13:57:39
***************
*** 4361,4368 ****
  mark_image (img)
       struct image *img;
  {
-   mark_object (&img->spec);
-   
    if (!NILP (img->data.lisp_val))
      mark_object (&img->data.lisp_val);
  }
--- 4361,4366 ----
***************
*** 4952,4957 ****
--- 4950,4957 ----
    /* Remove or mark entries in weak hash tables.
       This must be done before any object is unmarked.  */
    sweep_weak_hash_tables ();
+ 
+   sweep_image_caches ();
  
    sweep_strings ();
  #ifdef GC_CHECK_STRING_BYTES
*** xfns.c.~1.530.~     Sat Dec  1 14:54:43 2001
--- xfns.c      Sat Dec  1 15:13:59 2001
***************
*** 5752,5757 ****
--- 5752,5808 ----
  }
  
  
+ /* Free images whose Lisp specifications don't survive a GC.  */
+ 
+ void
+ sweep_image_caches ()
+ {
+   Lisp_Object tail, frame;
+ 
+   BLOCK_INPUT;
+ 
+   FOR_EACH_FRAME (tail, frame)
+     {
+       struct frame *f = XFRAME (frame);
+       
+       if (FRAME_LIVE_P (f) && FRAME_X_P (f))
+       {
+         struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
+         
+         if (c)
+           {
+             int i, nfreed = 0;
+             
+             for (i = 0; i < c->used; ++i)
+               if (c->images[i]
+                   && !survives_gc_p (c->images[i]->spec))
+                 {
+                   free_image (f, c->images[i]);
+ 
+                   if (++nfreed == 1)
+                     {
+                       Lisp_Object tail, frame;
+         
+                       FOR_EACH_FRAME (tail, frame)
+                         {
+                           struct frame *f = XFRAME (frame);
+                           if (FRAME_LIVE_P (f)
+                               && FRAME_X_P (f)
+                               && FRAME_X_IMAGE_CACHE (f) == c)
+                             clear_current_matrices (f);
+                         }
+       
+                       ++windows_or_buffers_changed;
+                     }
+                 }
+           }
+       }
+     }
+ 
+   UNBLOCK_INPUT;
+ }
+ 
+ 
  /* Prepare image IMG for display on frame F.  Must be called before
     drawing an image.  */
  





reply via email to

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