[Pcre-svn] [893] code/trunk: Experimental stack size determi…

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [893] code/trunk: Experimental stack size determination.
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 ||