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;