/[pcre]/code/trunk/pcre_jit_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 676 by ph10, Sat Aug 27 15:53:04 2011 UTC revision 677 by ph10, Sun Aug 28 10:50:07 2011 UTC
# Line 152  typedef struct jit_arguments { Line 152  typedef struct jit_arguments {
152    uschar *ptr;    uschar *ptr;
153    /* Everything else after. */    /* Everything else after. */
154    int offsetcount;    int offsetcount;
155      int calllimit;
156    uschar notbol;    uschar notbol;
157    uschar noteol;    uschar noteol;
158    uschar notempty;    uschar notempty;
# Line 280  typedef struct compiler_common { Line 281  typedef struct compiler_common {
281    recurse_entry *entries;    recurse_entry *entries;
282    recurse_entry *currententry;    recurse_entry *currententry;
283    jump_list *accept;    jump_list *accept;
284      jump_list *calllimit;
285    jump_list *stackalloc;    jump_list *stackalloc;
286    jump_list *revertframes;    jump_list *revertframes;
287    jump_list *wordboundary;    jump_list *wordboundary;
# Line 355  enum { Line 357  enum {
357  #define LOCALS_HEAD      (4 * sizeof(sljit_w))  #define LOCALS_HEAD      (4 * sizeof(sljit_w))
358  /* Head of the last recursion. */  /* Head of the last recursion. */
359  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))
360    /* Number of recursions. */
361    #define CALL_COUNT       (6 * sizeof(sljit_w))
362    /* Max limit of recursions. */
363    #define CALL_LIMIT       (7 * sizeof(sljit_w))
364  /* Last known position of the requested byte. */  /* Last known position of the requested byte. */
365  #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))  #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))
366  /* End pointer of the first line. */  /* End pointer of the first line. */
367  #define FIRSTLINE_END    (7 * sizeof(sljit_w))  #define FIRSTLINE_END    (9 * sizeof(sljit_w))
368  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
369  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
370  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
371  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
372  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (10 * sizeof(sljit_w))
373  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
374  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
375  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV(cc)         (common->localptrs[(cc) - common->start])
# Line 1175  while (list_item) Line 1181  while (list_item)
1181  common->stubs = NULL;  common->stubs = NULL;
1182  }  }
1183    
1184    static SLJIT_INLINE void decrease_call_count(compiler_common *common)
1185    {
1186    DEFINE_COMPILER;
1187    
1188    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_IMM, 1);
1189    add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1190    }
1191    
1192  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
1193  {  {
1194  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
# Line 3455  if (!minimize) Line 3469  if (!minimize)
3469    
3470    JUMPHERE(zerolength);    JUMPHERE(zerolength);
3471    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
3472    
3473      decrease_call_count(common);
3474    return cc;    return cc;
3475    }    }
3476    
# Line 3492  else if (max > 0) Line 3508  else if (max > 0)
3508  if (jump != NULL)  if (jump != NULL)
3509    JUMPHERE(jump);    JUMPHERE(jump);
3510  JUMPHERE(zerolength);  JUMPHERE(zerolength);
3511    
3512    decrease_call_count(common);
3513  return cc;  return cc;
3514  }  }
3515    
# Line 4212  if (bra == OP_BRAMINZERO) Line 4230  if (bra == OP_BRAMINZERO)
4230    /* Continue to the normal fallback. */    /* Continue to the normal fallback. */
4231    }    }
4232    
4233    if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
4234      decrease_call_count(common);
4235    
4236  /* Skip the other alternatives. */  /* Skip the other alternatives. */
4237  while (*cc == OP_ALT)  while (*cc == OP_ALT)
4238    cc += GET(cc, 1);    cc += GET(cc, 1);
# Line 4436  if (!zero) Line 4457  if (!zero)
4457    
4458  /* None of them matched. */  /* None of them matched. */
4459  set_jumps(emptymatch, LABEL());  set_jumps(emptymatch, LABEL());
4460    decrease_call_count(common);
4461  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4462  }  }
4463    
# Line 4696  switch(opcode) Line 4718  switch(opcode)
4718    break;    break;
4719    }    }
4720    
4721    decrease_call_count(common);
4722  return end;  return end;
4723  }  }
4724    
# Line 4939  while (cc < ccend) Line 4962  while (cc < ccend)
4962        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
4963        }        }
4964      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();
4965        if (cc[1] > OP_ASSERTBACK_NOT)
4966          decrease_call_count(common);
4967      break;      break;
4968    
4969      case OP_ONCE:      case OP_ONCE:
# Line 5969  common->stubs = NULL; Line 5994  common->stubs = NULL;
5994  common->entries = NULL;  common->entries = NULL;
5995  common->currententry = NULL;  common->currententry = NULL;
5996  common->accept = NULL;  common->accept = NULL;
5997    common->calllimit = NULL;
5998  common->stackalloc = NULL;  common->stackalloc = NULL;
5999  common->revertframes = NULL;  common->revertframes = NULL;
6000  common->wordboundary = NULL;  common->wordboundary = NULL;
# Line 6025  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_RE Line 6051  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_RE
6051  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
6052  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
6053  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
6054    OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit));
6055  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
6056  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
6057    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6058    
6059  /* Main part of the matching */  /* Main part of the matching */
6060  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
# Line 6043  if ((re->options & PCRE_ANCHORED) == 0) Line 6071  if ((re->options & PCRE_ANCHORED) == 0)
6071  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6072    reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0);    reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0);
6073    
6074    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
6075  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6076  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
6077    /* Copy the limit of allowed recursions. */
6078    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, TMP1, 0);
6079    
6080  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6081  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6171  JUMPHERE(alloc_error); Line 6202  JUMPHERE(alloc_error);
6202  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
6203  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6204    
6205    /* Call limit reached. */
6206    set_jumps(common->calllimit, LABEL());
6207    OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
6208    JUMPTO(SLJIT_JUMP, leave);
6209    
6210  if (common->revertframes != NULL)  if (common->revertframes != NULL)
6211    {    {
6212    set_jumps(common->revertframes, LABEL());    set_jumps(common->revertframes, LABEL());
# Line 6268  return convert_executable_func.call_exec Line 6304  return convert_executable_func.call_exec
6304    
6305  int  int
6306  _pcre_jit_exec(const real_pcre *re, void *executable_func,  _pcre_jit_exec(const real_pcre *re, void *executable_func,
6307    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,    PCRE_SPTR subject, int length, int start_offset, int options,
6308    int offsetcount)    int match_limit, int *offsets, int offsetcount)
6309  {  {
6310  executable_function *function = (executable_function*)executable_func;  executable_function *function = (executable_function*)executable_func;
6311  union {  union {
# Line 6285  arguments.stack = NULL; Line 6321  arguments.stack = NULL;
6321  arguments.str = subject + start_offset;  arguments.str = subject + start_offset;
6322  arguments.begin = subject;  arguments.begin = subject;
6323  arguments.end = subject + length;  arguments.end = subject + length;
6324    arguments.calllimit = match_limit; /* JIT decreases this value less times. */
6325  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
6326  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
6327  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;

Legend:
Removed from v.676  
changed lines
  Added in v.677

  ViewVC Help
Powered by ViewVC 1.1.5