Revision: 893
http://vcs.pcre.org/viewvc?view=rev&revision=893
Author: ph10
Date: 2012-01-19 17:15:11 +0000 (Thu, 19 Jan 2012)
Log Message:
-----------
Experimental stack size determination.
Modified Paths:
--------------
code/trunk/ChangeLog
code/trunk/pcre_exec.c
code/trunk/pcretest.c
Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog 2012-01-18 17:23:20 UTC (rev 892)
+++ code/trunk/ChangeLog 2012-01-19 17:15:11 UTC (rev 893)
@@ -57,6 +57,8 @@
15. Applied Graycode's patch to put the top-level frame on the stack rather
than the heap when not using the stack for recursion. This gives a
performance improvement in many cases when recursion is not deep.
+
+16. Experimental code added to "pcretest -C" to output the stack frame size.
Version 8.21 12-Dec-2011
Modified: code/trunk/pcre_exec.c
===================================================================
--- code/trunk/pcre_exec.c 2012-01-18 17:23:20 UTC (rev 892)
+++ code/trunk/pcre_exec.c 2012-01-19 17:15:11 UTC (rev 893)
@@ -615,6 +615,28 @@
int stacksave[REC_STACK_SAVE_MAX];
eptrblock newptrb;
+
+/* There is a special fudge for calling match() in a way that causes it to
+measure the size of its basic stack frame when the stack is being used for
+recursion. The first argument (eptr) points to a pointer that is used
+"statically" for doing the calculation. The second argument (ecode) being NULL
+triggers this behaviour. It cannot normally every be NULL. The return is the
+negated value of the frame size. */
+
+if (ecode == NULL)
+ {
+ char **aptr = (char **)eptr;
+ if (rdepth == 0)
+ {
+ *aptr = (char *)&rdepth;
+ return match(eptr, NULL, NULL, 0, NULL, NULL, 1);
+ }
+ else
+ {
+ int len = (char *)&rdepth - *aptr;
+ return (len > 0)? -len : len;
+ }
+ }
#endif /* NO_RECURSE */
/* To save space on the stack and in the heap frame, I have doubled up on some
@@ -6190,14 +6212,34 @@
const pcre_study_data *study;
const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
+/* Check for the special magic call that measures the size of the stack used
+per recursive call of match(). */
+
+if (re == NULL && extra_data == NULL && subject == NULL && length == -1)
+#ifdef NO_RECURSE
+ return -sizeof(heapframe);
+#else
+ return match((PCRE_PUCHAR)&start_partial, NULL, NULL, 0, NULL, NULL, 0);
+#endif
+
/* Plausibility checks */
if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
-if (re == NULL || subject == NULL ||
- (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
+if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))
+ return PCRE_ERROR_NULL;
if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
+/* Check that the first field in the block is the magic number. If it is not,
+return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
+REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
+means that the pattern is likely compiled with different endianness. */
+
+if (re->magic_number != MAGIC_NUMBER)
+ return re->magic_number == REVERSED_MAGIC_NUMBER?
+ PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
+if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+
/* These two settings are used in the code for checking a UTF-8 string that
follows immediately afterwards. Other values in the md block are used only
during "normal" pcre_exec() processing, not when the JIT support is in use,
@@ -6297,16 +6339,6 @@
if (tables == NULL) tables = PRIV(default_tables);
-/* Check that the first field in the block is the magic number. If it is not,
-return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
-REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
-means that the pattern is likely compiled with different endianness. */
-
-if (re->magic_number != MAGIC_NUMBER)
- return re->magic_number == REVERSED_MAGIC_NUMBER?
- PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
-if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
-
/* Set up other data */
anchored = ((re->options | options) & PCRE_ANCHORED) != 0;
Modified: code/trunk/pcretest.c
===================================================================
--- code/trunk/pcretest.c 2012-01-18 17:23:20 UTC (rev 892)
+++ code/trunk/pcretest.c 2012-01-19 17:15:11 UTC (rev 893)
@@ -2436,7 +2436,9 @@
(void)PCRE_CONFIG(PCRE_CONFIG_MATCH_LIMIT_RECURSION, &lrc);
printf(" Default recursion depth limit = %ld\n", lrc);
(void)PCRE_CONFIG(PCRE_CONFIG_STACKRECURSE, &rc);
- printf(" Match recursion uses %s\n", rc? "stack" : "heap");
+ printf(" Match recursion uses %s: ", rc? "stack" : "heap");
+ PCRE_EXEC(rc, NULL, NULL, NULL, -1, -1, 0, NULL, 0);
+ printf("frame size = %d bytes\n", -rc);
goto EXIT;
}
else if (strcmp(argv[op], "-help") == 0 ||