Index: regexp.c
===================================================================
--- regexp.c	(revision 205)
+++ regexp.c	(working copy)
@@ -378,14 +378,6 @@
 
 static char_u		*reg_prev_sub = NULL;
 
-#if defined(EXITFREE) || defined(PROTO)
-    void
-free_regexp_stuff()
-{
-    vim_free(reg_prev_sub);
-}
-#endif
-
 /*
  * REGEXP_INRANGE contains all characters which are always special in a []
  * range after '\'.
@@ -3332,7 +3324,21 @@
     return r;
 }
 
+
 /*
+ * Both for regstack and backpos tables we use the following strategy of
+ * allocation (to reduce malloc/free calls). "Initial" size is the size
+ * of table with which it is created. "Keep limit" size is the maximum
+ * size that we want to keep across vim_regexec_both() calls. The idea is
+ * simple: keep the memory across the calls as long as possible but don't
+ * allow to hold a lot of memory after some memory-requiring search.
+ */
+#define REGSTACK_INITIAL    8192
+#define BACKPOS_INITIAL     16
+#define REGSTACK_KEEP_LIMIT 16384
+#define BACKPOS_KEEP_LIMIT  32
+
+/*
  * Match a regexp against a string ("line" points to the string) or multiple
  * lines ("line" is NULL, use reg_getline()).
  */
@@ -3345,16 +3351,12 @@
     char_u	*s;
     long	retval = 0L;
 
-    reg_tofree = NULL;
+    if (regstack.ga_data == NULL)
+        ga_init2(&regstack, 1, REGSTACK_INITIAL);
 
-    /* Init the regstack empty.  Use an item size of 1 byte, since we push
-     * different things onto it.  Use a large grow size to avoid reallocating
-     * it too often. */
-    ga_init2(&regstack, 1, 10000);
+    if (backpos.ga_data == NULL)
+        ga_init2(&backpos, sizeof(backpos_T), BACKPOS_INITIAL);
 
-    /* Init the backpos table empty. */
-    ga_init2(&backpos, sizeof(backpos_T), 10);
-
     if (REG_MULTI)
     {
 	prog = reg_mmatch->regprog;
@@ -3524,9 +3526,18 @@
     }
 
 theend:
-    vim_free(reg_tofree);
-    ga_clear(&regstack);
-    ga_clear(&backpos);
+    /*
+     * Check regstack and backpos tables for their current size. If the size
+     * is higher than "keep limit" threshold - free the tables.
+     */
+    if (regstack.ga_maxlen >= REGSTACK_KEEP_LIMIT)
+    {
+        ga_clear(&regstack);
+    }
+    if (backpos.ga_maxlen >= BACKPOS_KEEP_LIMIT)
+    {
+        ga_clear(&backpos);
+    }
 
     return retval;
 }
@@ -3716,8 +3727,8 @@
 #define RA_MATCH	4	/* successful match */
 #define RA_NOMATCH	5	/* didn't match */
 
-  /* Init the regstack and backpos table empty.  They are initialized and
-   * freed in vim_regexec_both() to reduce malloc()/free() calls. */
+  /* Initialize tables regstack and backpos to empty state. They are
+   * managed in vim_regexec_both() to reduce malloc()/free() calls. */
   regstack.ga_len = 0;
   backpos.ga_len = 0;
 
@@ -7044,6 +7055,17 @@
     return (int)((dst - dest) + 1);
 }
 
+#if defined(EXITFREE) || defined(PROTO)
+    void
+free_regexp_stuff()
+{
+    ga_clear(&regstack);
+    ga_clear(&backpos);
+    vim_free(reg_tofree);
+    vim_free(reg_prev_sub);
+}
+#endif
+
 #ifdef FEAT_EVAL
 /*
  * Used for the submatch() function: get the string from tne n'th submatch in
