You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by br...@apache.org on 2002/03/21 05:17:11 UTC

cvs commit: httpd-2.0/srclib/pcre pcreposix.c

brianp      02/03/20 20:17:11

  Modified:    srclib/pcre pcreposix.c
  Log:
  Performance optimization: use a temp buffer on the stack instead
  of a malloc'ed buffer in regexec() in cases where the required
  buffer size is small.
  
  This will help us avoid a malloc/free pair when executing mod_rewrite
  rules that use $1/$2/etc to reference sequences in the matched pattern.
  
  Note: I've also submitted this change as a patch for PCRE, but because
  the next PCRE release isn't planned until later this year I'm
  committing it to the httpd-2.0 copy of PCRE in the meantime.
  
  Revision  Changes    Path
  1.5       +22 -4     httpd-2.0/srclib/pcre/pcreposix.c
  
  Index: pcreposix.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/srclib/pcre/pcreposix.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- pcreposix.c	20 Mar 2002 06:22:57 -0000	1.4
  +++ pcreposix.c	21 Mar 2002 04:17:11 -0000	1.5
  @@ -224,13 +224,23 @@
   the POSIX structures as was done in earlier releases when PCRE needed only 2
   ints. */
   
  +#define SMALL_NMATCH 5
   int
   regexec(regex_t *preg, const char *string, size_t nmatch,
     regmatch_t pmatch[], int eflags)
   {
   int rc;
   int options = 0;
  +/* NOTE: The code related to the "SMALL_NMATCH" optimization
  + * currently is unique to the httpd-2.0 copy of PCRE 3.9.  I've
  + * submitted the patch to the PCRE maintainer for inclusion in
  + * the next PCRE release, slated for late 2002.  At that time,
  + * we can merge the new PCRE version into the httpd-2.0/srclib
  + * tree.  --brianp 3/20/2002
  + */
  +int small_ovector[SMALL_NMATCH * 3];
   int *ovector = NULL;
  +int allocated_ovector = 0;
   
   if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL;
   if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL;
  @@ -244,8 +254,16 @@
   
   if (nmatch > 0)
     {
  -  ovector = (int *)malloc(sizeof(int) * nmatch * 3);
  -  if (ovector == NULL) return REG_ESPACE;
  +    if (nmatch <= SMALL_NMATCH)
  +      {
  +      ovector = &(small_ovector[0]);
  +      }
  +    else
  +      {
  +      ovector = (int *)malloc(sizeof(int) * nmatch * 3);
  +      if (ovector == NULL) return REG_ESPACE;
  +      allocated_ovector = 1;
  +      }
     }
   
   rc = pcre_exec(preg->re_pcre, NULL, string, (int)strlen(string), 0, options,
  @@ -261,14 +279,14 @@
       pmatch[i].rm_so = ovector[i*2];
       pmatch[i].rm_eo = ovector[i*2+1];
       }
  -  if (ovector != NULL) free(ovector);
  +  if (allocated_ovector) free(ovector);
     for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
     return 0;
     }
   
   else
     {
  -  if (ovector != NULL) free(ovector);
  +  if (allocated_ovector) free(ovector);
     switch(rc)
       {
       case PCRE_ERROR_NOMATCH: return REG_NOMATCH;