/[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 1002 by zherczeg, Tue Aug 14 09:31:00 2012 UTC revision 1009 by zherczeg, Wed Aug 22 12:01:22 2012 UTC
# Line 279  typedef struct compiler_common { Line 279  typedef struct compiler_common {
279    
280    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
281    int *private_data_ptrs;    int *private_data_ptrs;
282      /* Tells whether the capturing bracket is optimized. */
283      pcre_uint8 *optimized_cbracket;
284      /* Starting offset of private data for capturing brackets. */
285    int cbraptr;    int cbraptr;
286    /* OVector starting point. Must be divisible by 2. */    /* OVector starting point. Must be divisible by 2. */
287    int ovector_start;    int ovector_start;
# Line 759  static int get_private_data_length(compi Line 762  static int get_private_data_length(compi
762  {  {
763  int private_data_length = 0;  int private_data_length = 0;
764  pcre_uchar *alternative;  pcre_uchar *alternative;
765    pcre_uchar *name;
766  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
767  int space, size, bracketlen;  int space, size, bracketlen, i;
768    
769  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
770  while (cc < ccend)  while (cc < ccend)
# Line 775  while (cc < ccend) Line 779  while (cc < ccend)
779      cc += 1;      cc += 1;
780      break;      break;
781    
782        case OP_REF:
783        case OP_REFI:
784        common->optimized_cbracket[GET2(cc, 1)] = 0;
785        cc += 1 + IMM2_SIZE;
786        break;
787    
788      case OP_ASSERT:      case OP_ASSERT:
789      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
790      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 784  while (cc < ccend) Line 794  while (cc < ccend)
794      case OP_BRAPOS:      case OP_BRAPOS:
795      case OP_SBRA:      case OP_SBRA:
796      case OP_SBRAPOS:      case OP_SBRAPOS:
     case OP_SCOND:  
797      private_data_length += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
798      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
799      break;      break;
# Line 792  while (cc < ccend) Line 801  while (cc < ccend)
801      case OP_CBRAPOS:      case OP_CBRAPOS:
802      case OP_SCBRAPOS:      case OP_SCBRAPOS:
803      private_data_length += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
804        common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
805      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
806      break;      break;
807    
808      case OP_COND:      case OP_COND:
809      /* Might be a hidden SCOND. */      case OP_SCOND:
810      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
811      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
812          {
813          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
814          common->optimized_cbracket[bracketlen] = 0;
815          }
816        else if (bracketlen == OP_NCREF)
817          {
818          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
819          name = (pcre_uchar *)common->name_table;
820          alternative = name;
821          for (i = 0; i < common->name_count; i++)
822            {
823            if (GET2(name, 0) == bracketlen) break;
824            name += common->name_entry_size;
825            }
826          SLJIT_ASSERT(i != common->name_count);
827    
828          for (i = 0; i < common->name_count; i++)
829            {
830            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
831              common->optimized_cbracket[GET2(alternative, 0)] = 0;
832            alternative += common->name_entry_size;
833            }
834          }
835    
836        if (*cc == OP_COND)
837          {
838          /* Might be a hidden SCOND. */
839          alternative = cc + GET(cc, 1);
840          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
841            private_data_length += sizeof(sljit_w);
842          }
843        else
844        private_data_length += sizeof(sljit_w);        private_data_length += sizeof(sljit_w);
845      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
846      break;      break;
# Line 858  while (cc < ccend) Line 900  while (cc < ccend)
900  #endif  #endif
901    
902      case OP_RECURSE:      case OP_RECURSE:
903        alternative = common->start + GET(cc, 1);
904        if (alternative != common->start)
905          common->optimized_cbracket[GET2(alternative, 1 + LINK_SIZE)] = 0;
906      /* Set its value only once. */      /* Set its value only once. */
907      if (common->recursive_head == 0)      if (common->recursive_head == 0)
908        {        {
# Line 1252  while (cc < ccend) Line 1297  while (cc < ccend)
1297    
1298      case OP_CBRA:      case OP_CBRA:
1299      case OP_SCBRA:      case OP_SCBRA:
1300      private_data_length++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1301          private_data_length++;
1302      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1303      break;      break;
1304    
1305      case OP_CBRAPOS:      case OP_CBRAPOS:
1306      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1307        SLJIT_ASSERT(common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0);
1308      private_data_length += 2;      private_data_length += 2;
1309      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1310      break;      break;
# Line 1415  while (status != end) Line 1462  while (status != end)
1462    
1463        case OP_CBRA:        case OP_CBRA:
1464        case OP_SCBRA:        case OP_SCBRA:
1465        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1466        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1467            count = 1;
1468            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1469            }
1470        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1471        break;        break;
1472    
1473        case OP_CBRAPOS:        case OP_CBRAPOS:
1474        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1475        count = 2;        count = 2;
1476        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = PRIVATE_DATA(cc);
1477        srcw[1] = PRIVATE_DATA(cc);        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1478        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1479        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1480        break;        break;
1481    
# Line 5454  if (opcode == OP_CBRA || opcode == OP_SC Line 5504  if (opcode == OP_CBRA || opcode == OP_SC
5504    {    {
5505    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5506    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5507    private_data_ptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5508    offset <<= 1;      {
5509        private_data_ptr = OVECTOR_PRIV(offset);
5510        offset <<= 1;
5511        }
5512      else
5513        {
5514        offset <<= 1;
5515        private_data_ptr = OVECTOR(offset);
5516        }
5517    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5518    matchingpath += IMM2_SIZE;    matchingpath += IMM2_SIZE;
5519    }    }
# Line 5589  if (opcode == OP_ONCE) Line 5647  if (opcode == OP_ONCE)
5647  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5648    {    {
5649    /* Saving the previous values. */    /* Saving the previous values. */
5650    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5651    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5652    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5653    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5654    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5655    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5656    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5657    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5658        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5659        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5660        }
5661      else
5662        {
5663        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5664        allocate_stack(common, 2);
5665        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5666        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_w));
5667        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5668        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5669        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5670        }
5671    }    }
5672  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5673    {    {
# Line 6405  static SLJIT_INLINE pcre_uchar *compile_ Line 6476  static SLJIT_INLINE pcre_uchar *compile_
6476  {  {
6477  DEFINE_COMPILER;  DEFINE_COMPILER;
6478  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
6479    BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
6480    
6481  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
6482  if (common->currententry != NULL)  if (common->currententry != NULL)
6483    return cc + 1 + IMM2_SIZE;    return cc + 1 + IMM2_SIZE;
6484    
6485  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  if (!optimized_cbracket)
6486      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
6487  offset <<= 1;  offset <<= 1;
6488  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6489  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  if (!optimized_cbracket)
6490      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6491  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6492  }  }
6493    
# Line 7235  if (has_alternatives) Line 7309  if (has_alternatives)
7309  if (offset != 0)  if (offset != 0)
7310    {    {
7311    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7312    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    if (common->optimized_cbracket[offset >> 1] == 0)
7313    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      {
7314    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7315    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7316    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(2));      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7317    free_stack(common, 3);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7318        free_stack(common, 3);
7319        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7320        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7321        }
7322      else
7323        {
7324        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7325        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7326        free_stack(common, 2);
7327        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7328        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7329        }
7330    }    }
7331  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
7332    {    {
# Line 7727  ccend = bracketend(rootbacktrack.cc); Line 7813  ccend = bracketend(rootbacktrack.cc);
7813    
7814  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
7815  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
7816    common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
7817    if (!common->optimized_cbracket)
7818      return;
7819    memset(common->optimized_cbracket, 1, re->top_bracket + 1);
7820    
7821  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
7822  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
7823  if (private_data_size < 0)  if (private_data_size < 0)
7824      {
7825      SLJIT_FREE(common->optimized_cbracket);
7826    return;    return;
7827      }
7828    
7829  /* Checking flags and updating ovector_start. */  /* Checking flags and updating ovector_start. */
7830  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
# Line 7763  SLJIT_ASSERT(!(common->req_char_ptr != 0 Line 7856  SLJIT_ASSERT(!(common->req_char_ptr != 0
7856  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
7857  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
7858  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
7859      {
7860      SLJIT_FREE(common->optimized_cbracket);
7861    return;    return;
7862      }
7863  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
7864  if (!common->private_data_ptrs)  if (!common->private_data_ptrs)
7865      {
7866      SLJIT_FREE(common->optimized_cbracket);
7867    return;    return;
7868      }
7869  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
7870  set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);  set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
7871    
7872  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
7873  if (!compiler)  if (!compiler)
7874    {    {
7875      SLJIT_FREE(common->optimized_cbracket);
7876    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
7877    return;    return;
7878    }    }
# Line 7839  compile_matchingpath(common, rootbacktra Line 7939  compile_matchingpath(common, rootbacktra
7939  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7940    {    {
7941    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
7942      SLJIT_FREE(common->optimized_cbracket);
7943    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
7944    return;    return;
7945    }    }
# Line 7869  compile_backtrackingpath(common, rootbac Line 7970  compile_backtrackingpath(common, rootbac
7970  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7971    {    {
7972    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
7973      SLJIT_FREE(common->optimized_cbracket);
7974    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
7975    return;    return;
7976    }    }
# Line 7947  while (common->currententry != NULL) Line 8049  while (common->currententry != NULL)
8049    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8050      {      {
8051      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
8052        SLJIT_FREE(common->optimized_cbracket);
8053      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
8054      return;      return;
8055      }      }
# Line 8042  if (common->getucd != NULL) Line 8145  if (common->getucd != NULL)
8145    }    }
8146  #endif  #endif
8147    
8148    SLJIT_FREE(common->optimized_cbracket);
8149  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
8150  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
8151  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);

Legend:
Removed from v.1002  
changed lines
  Added in v.1009

  ViewVC Help
Powered by ViewVC 1.1.5