diff options
author | zherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2013-04-28 08:54:42 +0000 |
---|---|---|
committer | zherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2013-04-28 08:54:42 +0000 |
commit | b0944e58cd54455e3661cdb8248425fb78266e6e (patch) | |
tree | 90789c82b1dc1b9e97d377208409df3e01867c1e | |
parent | 94bbb126cebcb4560ca3e26ae69298bee2fa8cd1 (diff) | |
download | pcre-b0944e58cd54455e3661cdb8248425fb78266e6e.tar.gz |
Improved support for match_limit in JIT.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1316 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r-- | pcre_exec.c | 24 | ||||
-rw-r--r-- | pcre_jit_compile.c | 40 |
2 files changed, 23 insertions, 41 deletions
diff --git a/pcre_exec.c b/pcre_exec.c index cc15ca3..30976a1 100644 --- a/pcre_exec.c +++ b/pcre_exec.c @@ -6511,30 +6511,6 @@ if (extra_data != NULL && extra_data->executable_jit != NULL && (options & ~PUBLIC_JIT_EXEC_OPTIONS) == 0) { - /* A facility for setting the match limit in the regex was added; this puts - a value in the compiled block. (Similarly for recursion limit, but the JIT - does not make use of that.) Because the regex is not passed to jit_exec, we - fudge up an alternative extra block, because we must not modify the extra - block that the user has passed. */ - -#if defined COMPILE_PCRE8 - pcre_extra extra_data_copy; -#elif defined COMPILE_PCRE16 - pcre16_extra extra_data_copy; -#elif defined COMPILE_PCRE32 - pcre32_extra extra_data_copy; -#endif - - if ((re->flags & PCRE_MLSET) != 0 && - ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0 || - re->limit_match < extra_data->match_limit)) - { - extra_data_copy = *extra_data; - extra_data_copy.match_limit = re->limit_match; - extra_data_copy.flags |= PCRE_EXTRA_MATCH_LIMIT; - extra_data = &extra_data_copy; - } - rc = PRIV(jit_exec)(extra_data, (const pcre_uchar *)subject, length, start_offset, options, offsets, offsetcount); diff --git a/pcre_jit_compile.c b/pcre_jit_compile.c index f9c66f0..a2fd2e8 100644 --- a/pcre_jit_compile.c +++ b/pcre_jit_compile.c @@ -168,9 +168,9 @@ typedef struct jit_arguments { pcre_uchar *mark_ptr; void *callout_data; /* Everything else after. */ + pcre_uint32 limit_match; int real_offset_count; int offset_count; - int call_limit; pcre_uint8 notbol; pcre_uint8 noteol; pcre_uint8 notempty; @@ -182,6 +182,7 @@ typedef struct executable_functions { PUBL(jit_callback) callback; void *userdata; pcre_uint32 top_bracket; + pcre_uint32 limit_match; sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; } executable_functions; @@ -463,7 +464,7 @@ typedef struct compare_context { #define STACK_TOP SLJIT_SCRATCH_REG2 #define STACK_LIMIT SLJIT_SAVED_REG3 #define ARGUMENTS SLJIT_SAVED_EREG1 -#define CALL_COUNT SLJIT_SAVED_EREG2 +#define COUNT_MATCH SLJIT_SAVED_EREG2 #define RETURN_ADDR SLJIT_TEMPORARY_EREG1 /* Local space layout. */ @@ -474,7 +475,7 @@ typedef struct compare_context { #define POSSESSIVE0 (2 * sizeof(sljit_sw)) #define POSSESSIVE1 (3 * sizeof(sljit_sw)) /* Max limit of recursions. */ -#define CALL_LIMIT (4 * sizeof(sljit_sw)) +#define LIMIT_MATCH (4 * sizeof(sljit_sw)) /* The output vector is stored on the stack, and contains pointers to characters. The vector data is divided into two groups: the first group contains the start / end character pointers, and the second is @@ -2022,11 +2023,11 @@ while (list_item) common->stubs = NULL; } -static SLJIT_INLINE void decrease_call_count(compiler_common *common) +static SLJIT_INLINE void count_match(compiler_common *common) { DEFINE_COMPILER; -OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1); +OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1); add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO)); } @@ -5292,7 +5293,7 @@ if (!minimize) JUMPHERE(zerolength); BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); - decrease_call_count(common); + count_match(common); return cc; } @@ -5331,7 +5332,7 @@ if (jump != NULL) JUMPHERE(jump); JUMPHERE(zerolength); -decrease_call_count(common); +count_match(common); return cc; } @@ -6664,7 +6665,7 @@ if (bra == OP_BRAMINZERO) } if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) - decrease_call_count(common); + count_match(common); /* Skip the other alternatives. */ while (*cc == OP_ALT) @@ -6951,7 +6952,7 @@ if (!zero) /* None of them matched. */ set_jumps(emptymatch, LABEL()); -decrease_call_count(common); +count_match(common); return cc + 1 + LINK_SIZE; } @@ -7261,7 +7262,7 @@ switch(opcode) break; } -decrease_call_count(common); +count_match(common); return end; } @@ -7588,7 +7589,7 @@ while (cc < ccend) } BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL(); if (cc[1] > OP_ASSERTBACK_NOT) - decrease_call_count(common); + count_match(common); break; case OP_ONCE: @@ -8971,7 +8972,7 @@ common->use_ucp = (re->options & PCRE_UCP) != 0; ccend = bracketend(rootbacktrack.cc); /* Calculate the local space size on the stack. */ -common->ovector_start = CALL_LIMIT + sizeof(sljit_sw); +common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw); common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1); if (!common->optimized_cbracket) return; @@ -9103,10 +9104,10 @@ OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); -OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, call_limit)); +OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match)); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit)); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH, TMP1, 0); if (mode == JIT_PARTIAL_SOFT_COMPILE) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1); @@ -9148,7 +9149,7 @@ if (common->req_char_ptr != 0) /* Store the current STR_PTR in OVECTOR(0). */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0); /* Copy the limit of allowed recursions. */ -OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT); +OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH); if (common->capture_last_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1); @@ -9426,6 +9427,7 @@ else } memset(functions, 0, sizeof(executable_functions)); functions->top_bracket = (re->top_bracket + 1) * 2; + functions->limit_match = (re->flags & PCRE_MLSET) != 0 ? re->limit_match : 0; extra->executable_jit = functions; extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; } @@ -9480,7 +9482,9 @@ arguments.begin = subject; arguments.end = subject + length; arguments.mark_ptr = NULL; /* JIT decreases this value less frequently than the interpreter. */ -arguments.call_limit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit; +arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit); +if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match) + arguments.limit_match = functions->limit_match; arguments.notbol = (options & PCRE_NOTBOL) != 0; arguments.noteol = (options & PCRE_NOTEOL) != 0; arguments.notempty = (options & PCRE_NOTEMPTY) != 0; @@ -9571,7 +9575,9 @@ arguments.begin = subject_ptr; arguments.end = subject_ptr + length; arguments.mark_ptr = NULL; /* JIT decreases this value less frequently than the interpreter. */ -arguments.call_limit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit; +arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit); +if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match) + arguments.limit_match = functions->limit_match; arguments.notbol = (options & PCRE_NOTBOL) != 0; arguments.noteol = (options & PCRE_NOTEOL) != 0; arguments.notempty = (options & PCRE_NOTEMPTY) != 0; |