Document JIT compile size limit and give more info in pcre2test.

This commit is contained in:
Philip.Hazel 2015-11-14 16:48:32 +00:00
parent 860b6f228a
commit 7a233130ad
4 changed files with 39 additions and 18 deletions

View File

@ -304,6 +304,9 @@ newline sequence.
90. Run test 8 (internal offsets and code sizes) for link sizes 3 and 4 as well 90. Run test 8 (internal offsets and code sizes) for link sizes 3 and 4 as well
as for link size 2. as for link size 2.
91. Document that JIT has a limit on pattern size, and give more information
about JIT compile failures in pcre2test.
Version 10.20 30-June-2015 Version 10.20 30-June-2015
-------------------------- --------------------------

View File

@ -1,4 +1,4 @@
.TH PCRE2JIT 3 "28 July 2014" "PCRE2 10.21" .TH PCRE2JIT 3 "14 November 2015" "PCRE2 10.21"
.SH NAME .SH NAME
PCRE2 - Perl-compatible regular expressions (revised API) PCRE2 - Perl-compatible regular expressions (revised API)
.SH "PCRE2 JUST-IN-TIME COMPILER SUPPORT" .SH "PCRE2 JUST-IN-TIME COMPILER SUPPORT"
@ -61,6 +61,12 @@ much faster than the normal interpretive code, but yields exactly the same
results. The returned value from \fBpcre2_jit_compile()\fP is zero on success, results. The returned value from \fBpcre2_jit_compile()\fP is zero on success,
or a negative error code. or a negative error code.
.P .P
There is a limit to the size of pattern that JIT supports, imposed by the size
of machine stack that it uses. The exact rules are not documented because they
may change at any time, in particular, when new optimizations are introduced.
If a pattern is too big, a call to \fBpcre2_jit_compile()\fB returns
PCRE2_ERROR_NOMEMORY.
.P
PCRE2_JIT_COMPLETE requests the JIT compiler to generate code for complete PCRE2_JIT_COMPLETE requests the JIT compiler to generate code for complete
matches. If you want to run partial matches using the PCRE2_PARTIAL_HARD or matches. If you want to run partial matches using the PCRE2_PARTIAL_HARD or
PCRE2_PARTIAL_SOFT options of \fBpcre2_match()\fP, you should set one or both PCRE2_PARTIAL_SOFT options of \fBpcre2_match()\fP, you should set one or both
@ -404,6 +410,6 @@ Cambridge, England.
.rs .rs
.sp .sp
.nf .nf
Last updated: 28 July 2015 Last updated: 14 November 2015
Copyright (c) 1997-2015 University of Cambridge. Copyright (c) 1997-2015 University of Cambridge.
.fi .fi

View File

@ -735,6 +735,7 @@ static BOOL restrict_for_perl_test = FALSE;
static BOOL show_memory = FALSE; static BOOL show_memory = FALSE;
static int code_unit_size; /* Bytes */ static int code_unit_size; /* Bytes */
static int jitrc; /* Return from JIT compile */
static int test_mode = DEFAULT_TEST_MODE; static int test_mode = DEFAULT_TEST_MODE;
static int timeit = 0; static int timeit = 0;
static int timeitm = 0; static int timeitm = 0;
@ -936,10 +937,10 @@ are supported. */
else \ else \
a = pcre2_get_startchar_32(G(b,32)) a = pcre2_get_startchar_32(G(b,32))
#define PCRE2_JIT_COMPILE(a,b) \ #define PCRE2_JIT_COMPILE(r,a,b) \
if (test_mode == PCRE8_MODE) pcre2_jit_compile_8(G(a,8),b); \ if (test_mode == PCRE8_MODE) r = pcre2_jit_compile_8(G(a,8),b); \
else if (test_mode == PCRE16_MODE) pcre2_jit_compile_16(G(a,16),b); \ else if (test_mode == PCRE16_MODE) r = pcre2_jit_compile_16(G(a,16),b); \
else pcre2_jit_compile_32(G(a,32),b) else r = pcre2_jit_compile_32(G(a,32),b)
#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) \ #define PCRE2_JIT_FREE_UNUSED_MEMORY(a) \
if (test_mode == PCRE8_MODE) pcre2_jit_free_unused_memory_8(G(a,8)); \ if (test_mode == PCRE8_MODE) pcre2_jit_free_unused_memory_8(G(a,8)); \
@ -1379,11 +1380,11 @@ the three different cases. */
else \ else \
a = G(pcre2_get_startchar_,BITTWO)(G(b,BITTWO)) a = G(pcre2_get_startchar_,BITTWO)(G(b,BITTWO))
#define PCRE2_JIT_COMPILE(a,b) \ #define PCRE2_JIT_COMPILE(r,a,b) \
if (test_mode == G(G(PCRE,BITONE),_MODE)) \ if (test_mode == G(G(PCRE,BITONE),_MODE)) \
G(pcre2_jit_compile_,BITONE)(G(a,BITONE),b); \ r = G(pcre2_jit_compile_,BITONE)(G(a,BITONE),b); \
else \ else \
G(pcre2_jit_compile_,BITTWO)(G(a,BITTWO),b) r = G(pcre2_jit_compile_,BITTWO)(G(a,BITTWO),b)
#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) \ #define PCRE2_JIT_FREE_UNUSED_MEMORY(a) \
if (test_mode == G(G(PCRE,BITONE),_MODE)) \ if (test_mode == G(G(PCRE,BITONE),_MODE)) \
@ -1690,7 +1691,7 @@ the three different cases. */
r = pcre2_get_error_message_8(a,G(b,8),G(G(b,8),_size)) r = pcre2_get_error_message_8(a,G(b,8),G(G(b,8),_size))
#define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_8(G(b,8)) #define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_8(G(b,8))
#define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_8(G(b,8)) #define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_8(G(b,8))
#define PCRE2_JIT_COMPILE(a,b) pcre2_jit_compile_8(G(a,8),b) #define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_8(G(a,8),b)
#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_8(G(a,8)) #define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_8(G(a,8))
#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \ #define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \
a = pcre2_jit_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h) a = pcre2_jit_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),h)
@ -1783,7 +1784,7 @@ the three different cases. */
r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size)) r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size))
#define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_16(G(b,16)) #define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_16(G(b,16))
#define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_16(G(b,16)) #define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_16(G(b,16))
#define PCRE2_JIT_COMPILE(a,b) pcre2_jit_compile_16(G(a,16),b) #define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_16(G(a,16),b)
#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_16(G(a,16)) #define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_16(G(a,16))
#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \ #define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \
a = pcre2_jit_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h) a = pcre2_jit_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),h)
@ -1876,7 +1877,7 @@ the three different cases. */
r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size)) r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size))
#define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_32(G(b,32)) #define PCRE2_GET_OVECTOR_COUNT(a,b) a = pcre2_get_ovector_count_32(G(b,32))
#define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_32(G(b,32)) #define PCRE2_GET_STARTCHAR(a,b) a = pcre2_get_startchar_32(G(b,32))
#define PCRE2_JIT_COMPILE(a,b) pcre2_jit_compile_32(G(a,32),b) #define PCRE2_JIT_COMPILE(r,a,b) r = pcre2_jit_compile_32(G(a,32),b)
#define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_32(G(a,32)) #define PCRE2_JIT_FREE_UNUSED_MEMORY(a) pcre2_jit_free_unused_memory_32(G(a,32))
#define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \ #define PCRE2_JIT_MATCH(a,b,c,d,e,f,g,h) \
a = pcre2_jit_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h) a = pcre2_jit_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),h)
@ -3976,13 +3977,24 @@ if ((pat_patctl.control & CTL_INFO) != 0)
if (FLD(compiled_code, executable_jit) != NULL) if (FLD(compiled_code, executable_jit) != NULL)
fprintf(outfile, "JIT compilation was successful\n"); fprintf(outfile, "JIT compilation was successful\n");
else else
{
#ifdef SUPPORT_JIT #ifdef SUPPORT_JIT
fprintf(outfile, "JIT compilation was not successful\n"); int len;
fprintf(outfile, "JIT compilation was not successful");
if (jitrc != 0)
{
fprintf(outfile, " (");
PCRE2_GET_ERROR_MESSAGE(len, jitrc, pbuffer);
PCHARSV(CASTVAR(void *, pbuffer), 0, len, FALSE, outfile);
fprintf(outfile, ")");
}
fprintf(outfile, "\n");
#else #else
fprintf(outfile, "JIT support is not available in this version of PCRE2\n"); fprintf(outfile, "JIT support is not available in this version of PCRE2\n");
#endif #endif
} }
} }
}
if ((pat_patctl.control & CTL_CALLOUT_INFO) != 0) if ((pat_patctl.control & CTL_CALLOUT_INFO) != 0)
{ {
@ -4191,7 +4203,7 @@ switch(cmd)
SET(compiled_code, patstack[--patstacknext]); SET(compiled_code, patstack[--patstacknext]);
if (pat_patctl.jit != 0) if (pat_patctl.jit != 0)
{ {
PCRE2_JIT_COMPILE(compiled_code, pat_patctl.jit); PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit);
} }
if ((pat_patctl.control & CTL_MEMORY) != 0) show_memory_info(); if ((pat_patctl.control & CTL_MEMORY) != 0) show_memory_info();
if ((pat_patctl.control & CTL_ANYINFO) != 0) if ((pat_patctl.control & CTL_ANYINFO) != 0)
@ -4776,7 +4788,7 @@ if (pat_patctl.jit != 0)
pat_patctl.options|forbid_utf, &errorcode, &erroroffset, pat_patctl.options|forbid_utf, &errorcode, &erroroffset,
use_pat_context); use_pat_context);
start_time = clock(); start_time = clock();
PCRE2_JIT_COMPILE(compiled_code, pat_patctl.jit); PCRE2_JIT_COMPILE(jitrc,compiled_code, pat_patctl.jit);
time_taken += clock() - start_time; time_taken += clock() - start_time;
} }
total_jit_compile_time += time_taken; total_jit_compile_time += time_taken;
@ -4786,7 +4798,7 @@ if (pat_patctl.jit != 0)
} }
else else
{ {
PCRE2_JIT_COMPILE(compiled_code, pat_patctl.jit); PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit);
} }
} }

View File

@ -9,7 +9,7 @@
Capturing subpattern count = 0 Capturing subpattern count = 0
May match empty string May match empty string
Subject length lower bound = 0 Subject length lower bound = 0
JIT compilation was not successful JIT compilation was not successful (no more memory)
# The following pattern cannot be compiled by JIT. # The following pattern cannot be compiled by JIT.
@ -17,7 +17,7 @@ JIT compilation was not successful
Capturing subpattern count = 0 Capturing subpattern count = 0
May match empty string May match empty string
Subject length lower bound = 0 Subject length lower bound = 0
JIT compilation was not successful JIT compilation was not successful (no more memory)
# Check that an infinite recursion loop is caught. # Check that an infinite recursion loop is caught.