/[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 1437 by zherczeg, Fri Jan 10 08:52:20 2014 UTC revision 1440 by zherczeg, Sat Jan 11 21:54:20 2014 UTC
# Line 3345  while (TRUE) Line 3345  while (TRUE)
3345        chars[0] = mask;        chars[0] = mask;
3346        chars[1] = mask;        chars[1] = mask;
3347    
3348          consumed++;
3349        if (--max_chars == 0)        if (--max_chars == 0)
3350          return consumed;          return consumed;
       consumed++;  
3351        chars += 2;        chars += 2;
3352        }        }
3353      while (--repeat > 0);      while (--repeat > 0);
# Line 3396  while (TRUE) Line 3396  while (TRUE)
3396          chr |= mask;          chr |= mask;
3397          }          }
3398    
3399    #ifdef COMPILE_PCRE32
3400          if (chars[0] == NOTACHAR && chars[1] == 0)
3401    #else
3402        if (chars[0] == NOTACHAR)        if (chars[0] == NOTACHAR)
3403    #endif
3404          {          {
3405          chars[0] = chr;          chars[0] = chr;
3406          chars[1] = mask;          chars[1] = mask;
# Line 3410  while (TRUE) Line 3414  while (TRUE)
3414          }          }
3415    
3416        len--;        len--;
3417          consumed++;
3418        if (--max_chars == 0)        if (--max_chars == 0)
3419          return consumed;          return consumed;
       consumed++;  
3420        chars += 2;        chars += 2;
3421        cc++;        cc++;
3422        }        }
# Line 3432  while (TRUE) Line 3436  while (TRUE)
3436  }  }
3437    
3438  #define MAX_N_CHARS 16  #define MAX_N_CHARS 16
3439    #define MIN_RANGE_SIZE 4
3440    
3441  static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)  static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
3442  {  {
# Line 3440  struct sljit_label *start; Line 3445  struct sljit_label *start;
3445  struct sljit_jump *quit;  struct sljit_jump *quit;
3446  pcre_uint32 chars[MAX_N_CHARS * 2];  pcre_uint32 chars[MAX_N_CHARS * 2];
3447  pcre_uint8 ones[MAX_N_CHARS];  pcre_uint8 ones[MAX_N_CHARS];
 pcre_uint32 mask;  
 int i, max;  
3448  int offsets[3];  int offsets[3];
3449    pcre_uint32 mask, byte;
3450    int i, max, from;
3451    int range_right = -1, range_len = -1;
3452    sljit_ub *update_table = NULL;
3453    BOOL in_range;
3454    
3455    /* This is even TRUE, if both are NULL. */
3456    SLJIT_ASSERT(common->read_only_data_ptr == common->read_only_data);
3457    
3458  for (i = 0; i < MAX_N_CHARS; i++)  for (i = 0; i < MAX_N_CHARS; i++)
3459    {    {
# Line 3467  for (i = 0; i < max; i++) Line 3478  for (i = 0; i < max; i++)
3478      }      }
3479    }    }
3480    
3481    in_range = FALSE;
3482    for (i = 0; i <= max; i++)
3483      {
3484      if (i < max && ones[i] <= 1)
3485        {
3486        if (!in_range)
3487          {
3488          in_range = TRUE;
3489          from = i;
3490          }
3491        }
3492      else if (in_range)
3493        {
3494        if (range_len == -1 || (i - from) > range_len)
3495          {
3496          range_len = i - from;
3497          range_right = i - 1;
3498          }
3499        in_range = FALSE;
3500        }
3501      }
3502    
3503    if (range_len >= MIN_RANGE_SIZE)
3504      {
3505      /* Since no data is consumed (see the assert in the beginning
3506      of this function), this space can be reallocated. */
3507      if (common->read_only_data)
3508        SLJIT_FREE(common->read_only_data);
3509    
3510      common->read_only_data_size += 256;
3511      common->read_only_data = (sljit_uw *)SLJIT_MALLOC(common->read_only_data_size);
3512      if (common->read_only_data == NULL)
3513        return TRUE;
3514    
3515      update_table = (sljit_ub *)common->read_only_data;
3516      common->read_only_data_ptr = (sljit_uw *)(update_table + 256);
3517      memset(update_table, IN_UCHARS(range_len), 256);
3518    
3519      for (i = 0; i < range_len; i++)
3520        {
3521        byte = chars[(range_right - i) << 1] & 0xff;
3522        if (update_table[byte] > IN_UCHARS(i))
3523          update_table[byte] = IN_UCHARS(i);
3524        mask = chars[((range_right - i) << 1) + 1] & 0xff;
3525        if (mask != 0)
3526          {
3527          byte ^= mask;
3528          if (update_table[byte] > IN_UCHARS(i))
3529            update_table[byte] = IN_UCHARS(i);
3530          }
3531        }
3532      }
3533    
3534  offsets[0] = -1;  offsets[0] = -1;
3535  /* Scan forward. */  /* Scan forward. */
3536  for (i = 0; i < max; i++)  for (i = 0; i < max; i++)
# Line 3481  if (offsets[0] == -1) Line 3545  if (offsets[0] == -1)
3545  /* Scan backward. */  /* Scan backward. */
3546  offsets[1] = -1;  offsets[1] = -1;
3547  for (i = max - 1; i > offsets[0]; i--)  for (i = max - 1; i > offsets[0]; i--)
3548    if (ones[i] <= 2) {    if (ones[i] <= 2 && i != range_right)
3549        {
3550      offsets[1] = i;      offsets[1] = i;
3551      break;      break;
3552    }      }
3553    
3554    /* This case is handled better by fast_forward_first_char. */
3555    if (offsets[1] == -1 && offsets[0] == 0)
3556      return FALSE;
3557    
3558  offsets[2] = -1;  offsets[2] = -1;
3559  if (offsets[1] >= 0)  if (offsets[1] >= 0 && range_right == -1)
3560    {    {
3561    /* Scan from middle. */    /* Scan from middle. */
3562    for (i = (offsets[0] + offsets[1]) / 2 + 1; i < offsets[1]; i++)    for (i = (offsets[0] + offsets[1]) / 2 + 1; i < offsets[1]; i++)
# Line 3528  max -= 1; Line 3597  max -= 1;
3597  if (firstline)  if (firstline)
3598    {    {
3599    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
3600      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
3601    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3602    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS(max));    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
3603      quit = CMP(SLJIT_C_LESS_EQUAL, STR_END, 0, TMP1, 0);
3604      OP1(SLJIT_MOV, STR_END, 0, TMP1, 0);
3605      JUMPHERE(quit);
3606    }    }
3607  else  else
3608    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
3609    
3610    #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
3611    if (range_len >= MIN_RANGE_SIZE)
3612      OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table);
3613    #endif
3614    
3615  start = LABEL();  start = LABEL();
3616  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3617    
3618    if (range_len >= MIN_RANGE_SIZE)
3619      {
3620    #if defined COMPILE_PCRE8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
3621      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right));
3622    #else
3623      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1);
3624    #endif
3625    
3626    #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
3627      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0);
3628    #else
3629      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table);
3630    #endif
3631      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3632      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start);
3633      }
3634    
3635  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[0]));  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[0]));
3636  if (offsets[1] >= 0)  if (offsets[1] >= 0)
3637    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[1]));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[1]));
# Line 3566  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, S Line 3661  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, S
3661  JUMPHERE(quit);  JUMPHERE(quit);
3662    
3663  if (firstline)  if (firstline)
3664      {
3665      if (range_len >= MIN_RANGE_SIZE)
3666        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
3667    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3668      if (range_len >= MIN_RANGE_SIZE)
3669        {
3670        quit = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
3671        OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
3672        JUMPHERE(quit);
3673        }
3674      }
3675  else  else
3676    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
3677  return TRUE;  return TRUE;
3678  }  }
3679    
3680  #undef MAX_N_CHARS  #undef MAX_N_CHARS
3681    #undef MIN_RANGE_SIZE
3682    
3683  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
3684  {  {
# Line 9808  if ((re->options & PCRE_ANCHORED) == 0) Line 9914  if ((re->options & PCRE_ANCHORED) == 0)
9914    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
9915      {      {
9916      if (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0))      if (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0))
9917        { /* Do nothing */ }        {
9918          /* If read_only_data is reallocated, we might have an allocation failure. */
9919          if (common->read_only_data_size > 0 && common->read_only_data == NULL)
9920            {
9921            sljit_free_compiler(compiler);
9922            SLJIT_FREE(common->optimized_cbracket);
9923            SLJIT_FREE(common->private_data_ptrs);
9924            return;
9925            }
9926          }
9927      else if ((re->flags & PCRE_FIRSTSET) != 0)      else if ((re->flags & PCRE_FIRSTSET) != 0)
9928        fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
9929      else if ((re->flags & PCRE_STARTLINE) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)

Legend:
Removed from v.1437  
changed lines
  Added in v.1440

  ViewVC Help
Powered by ViewVC 1.1.5