diff options
author | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2012-01-19 17:15:11 +0000 |
---|---|---|
committer | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2012-01-19 17:15:11 +0000 |
commit | 4113dfcc0bc064a56d1097667bb0140d2d137b71 (patch) | |
tree | 2411eeaa7fa64340346eb729c082befa7aa2b768 | |
parent | 758fe889107e073a9d7fd63d3f47c18519a0d0ae (diff) | |
download | pcre-4113dfcc0bc064a56d1097667bb0140d2d137b71.tar.gz |
Experimental stack size determination.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@893 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | pcre_exec.c | 56 | ||||
-rw-r--r-- | pcretest.c | 4 |
3 files changed, 49 insertions, 13 deletions
@@ -57,6 +57,8 @@ Version 8.30 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 diff --git a/pcre_exec.c b/pcre_exec.c index 02f7576..2bcf716 100644 --- a/pcre_exec.c +++ b/pcre_exec.c @@ -615,6 +615,28 @@ int save_offset1, save_offset2, save_offset3; 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 @@ PCRE_PUCHAR req_char_ptr = start_match - 1; 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 @@ in other programs later. */ 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; @@ -2436,7 +2436,9 @@ are set, either both UTFs are supported or both are not supported. */ (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 || |