Patch 7.0.084
Problem:    The garbage collector may do its work while some Lists or
            Dictionaries are used internally, e.g., by ":echo" that runs into
            the more-prompt or ":echo [garbagecollect()]".
Solution:   Only do garbage collection when waiting for a character at the
            toplevel.  Let garbagecollect() set a flag that is handled at the
            toplevel before waiting for a character.
Files:      src/eval.c, src/getchar.c, src/globals.h, src/main.c


*** ../vim-7.0.083/src/eval.c   Sun Sep  3 15:38:02 2006
--- src/eval.c  Tue Sep  5 11:49:38 2006
***************
*** 6074,6079 ****
--- 6074,6083 ----
      tabpage_T *tp;
  #endif
  
+     /* Only do this once. */
+     want_garbage_collect = FALSE;
+     may_garbage_collect = FALSE;
+ 
      /*
       * 1. Go through all accessible variables and mark all lists and dicts
       *    with copyID.
***************
*** 9636,9642 ****
      typval_T  *argvars;
      typval_T  *rettv;
  {
!     garbage_collect();
  }
  
  /*
--- 9640,9648 ----
      typval_T  *argvars;
      typval_T  *rettv;
  {
!     /* This is postponed until we are back at the toplevel, because we may be
!      * using Lists and Dicts internally.  E.g.: ":echo [garbagecollect()]". */
!     want_garbage_collect = TRUE;
  }
  
  /*
*** ../vim-7.0.083/src/getchar.c        Wed May  3 23:19:24 2006
--- src/getchar.c       Tue Sep  5 12:55:54 2006
***************
*** 1451,1457 ****
  {
      updatescript(0);
  #ifdef FEAT_EVAL
!     garbage_collect();
  #endif
  }
  
--- 1451,1458 ----
  {
      updatescript(0);
  #ifdef FEAT_EVAL
!     if (may_garbage_collect)
!       garbage_collect();
  #endif
  }
  
***************
*** 1502,1507 ****
--- 1503,1515 ----
      int               i;
  #endif
  
+ #ifdef FEAT_EVAL
+     /* Do garbage collection when garbagecollect() was called previously and
+      * we are now at the toplevel. */
+     if (may_garbage_collect && want_garbage_collect)
+       garbage_collect();
+ #endif
+ 
      /*
       * If a character was put back with vungetc, it was already processed.
       * Return it directly.
***************
*** 1511,1523 ****
        c = old_char;
        old_char = -1;
        mod_mask = old_mod_mask;
-       return c;
      }
! 
!     mod_mask = 0x0;
!     last_recorded_len = 0;
!     for (;;)                  /* this is done twice if there are modifiers */
      {
        if (mod_mask)           /* no mapping after modifier has been read */
        {
            ++no_mapping;
--- 1519,1531 ----
        c = old_char;
        old_char = -1;
        mod_mask = old_mod_mask;
      }
!     else
      {
+       mod_mask = 0x0;
+       last_recorded_len = 0;
+       for (;;)                        /* this is done twice if there are 
modifiers */
+       {
        if (mod_mask)           /* no mapping after modifier has been read */
        {
            ++no_mapping;
***************
*** 1695,1702 ****
        }
  #endif
  
!       return c;
      }
  }
  
  /*
--- 1703,1722 ----
        }
  #endif
  
!       break;
!       }
      }
+ 
+ #ifdef FEAT_EVAL
+     /*
+      * In the main loop "may_garbage_collect" can be set to do garbage
+      * collection in the first next vgetc().  It's disabled after that to
+      * avoid internally used Lists and Dicts to be freed.
+      */
+     may_garbage_collect = FALSE;
+ #endif
+ 
+     return c;
  }
  
  /*
*** ../vim-7.0.083/src/globals.h        Sat Sep  2 14:52:41 2006
--- src/globals.h       Tue Sep  5 11:46:10 2006
***************
*** 300,308 ****
  #endif
  
  #ifdef FEAT_EVAL
! EXTERN scid_T current_SID INIT(= 0);      /* ID of script being sourced or
!                                              was sourced to define the
!                                              current function. */
  #endif
  
  #if defined(FEAT_EVAL) || defined(FEAT_SYN_HL)
--- 300,315 ----
  #endif
  
  #ifdef FEAT_EVAL
! /* Garbage collection can only take place when we are sure there are no Lists
!  * or Dictionaries being used internally.  This is flagged with
!  * "may_garbage_collect" when we are at the toplevel.
!  * "want_garbage_collect" is set by the garbagecollect() function, which means
!  * we do garbage collection before waiting for a char at the toplevel. */
! EXTERN int    may_garbage_collect INIT(= FALSE);
! EXTERN int    want_garbage_collect INIT(= FALSE);
! 
! /* ID of script being sourced or was sourced to define the current function. 
*/
! EXTERN scid_T current_SID INIT(= 0);
  #endif
  
  #if defined(FEAT_EVAL) || defined(FEAT_SYN_HL)
*** ../vim-7.0.083/src/main.c   Tue Aug 29 17:28:56 2006
--- src/main.c  Tue Sep  5 12:33:47 2006
***************
*** 1130,1135 ****
--- 1130,1145 ----
         */
        update_curswant();
  
+ #ifdef FEAT_EVAL
+       /*
+        * May perform garbage collection when waiting for a character, but
+        * only at the very toplevel.  Otherwise we may be using a List or
+        * Dict internally somewhere.
+        * "may_garbage_collect" is reset in vgetc() which is invoked through
+        * do_exmode() and normal_cmd().
+        */
+       may_garbage_collect = (!cmdwin && !noexmode);
+ #endif
        /*
         * If we're invoked as ex, do a round of ex commands.
         * Otherwise, get and execute a normal mode command.
*** ../vim-7.0.083/src/version.c        Sun Sep  3 16:39:51 2006
--- src/version.c       Tue Sep  5 12:51:28 2006
***************
*** 668,669 ****
--- 668,671 ----
  {   /* Add new patch number below this line */
+ /**/
+     84,
  /**/

-- 
LAUNCELOT: At last!   A call!  A cry of distress ...
           (he draws his sword, and turns to CONCORDE)
           Concorde!  Brave, Concorde ... you shall not have died in vain!
CONCORDE:  I'm not quite dead, sir ...
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- [EMAIL PROTECTED] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

Reply via email to