/[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 1508 by zherczeg, Mon Oct 6 06:55:29 2014 UTC revision 1533 by zherczeg, Tue Mar 24 08:22:29 2015 UTC
# Line 179  typedef struct jit_arguments { Line 179  typedef struct jit_arguments {
179    
180  typedef struct executable_functions {  typedef struct executable_functions {
181    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
182    sljit_uw *read_only_data[JIT_NUMBER_OF_COMPILE_MODES];    void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES];
183    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
184    PUBL(jit_callback) callback;    PUBL(jit_callback) callback;
185    void *userdata;    void *userdata;
# Line 322  typedef struct compiler_common { Line 322  typedef struct compiler_common {
322    pcre_uchar *start;    pcre_uchar *start;
323    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
324    sljit_si *private_data_ptrs;    sljit_si *private_data_ptrs;
325    /* This read-only data is available during runtime. */    /* Chain list of read-only data ptrs. */
326    sljit_uw *read_only_data;    void *read_only_data_head;
   /* The total size of the read-only data. */  
   sljit_uw read_only_data_size;  
   /* The next free entry of the read_only_data. */  
   sljit_uw *read_only_data_ptr;  
327    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
328    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
329    /* Tells whether the starting offset is a target of then. */    /* Tells whether the starting offset is a target of then. */
# Line 802  while (cc < ccend) Line 798  while (cc < ccend)
798      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
799      break;      break;
800    
     case OP_BRA:  
     case OP_CBRA:  
     case OP_SBRA:  
     case OP_SCBRA:  
     count = no_alternatives(cc);  
     if (count > 4)  
       common->read_only_data_size += count * sizeof(sljit_uw);  
     cc += 1 + LINK_SIZE + (*cc == OP_CBRA || *cc == OP_SCBRA ? IMM2_SIZE : 0);  
     break;  
   
801      case OP_CBRAPOS:      case OP_CBRAPOS:
802      case OP_SCBRAPOS:      case OP_SCBRAPOS:
803      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
# Line 2114  DEFINE_COMPILER; Line 2100  DEFINE_COMPILER;
2100  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
2101  }  }
2102    
2103    static sljit_uw * allocate_read_only_data(compiler_common *common, sljit_uw size)
2104    {
2105    DEFINE_COMPILER;
2106    sljit_uw *result;
2107    
2108    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
2109      return NULL;
2110    
2111    result = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), compiler->allocator_data);
2112    if (SLJIT_UNLIKELY(result == NULL))
2113      {
2114      sljit_set_compiler_memory_error(compiler);
2115      return NULL;
2116      }
2117    
2118    *(void**)result = common->read_only_data_head;
2119    common->read_only_data_head = (void *)result;
2120    return result + 1;
2121    }
2122    
2123    static void free_read_only_data(void *current, void *allocator_data)
2124    {
2125    void *next;
2126    
2127    SLJIT_UNUSED_ARG(allocator_data);
2128    
2129    while (current != NULL)
2130      {
2131      next = *(void**)current;
2132      SLJIT_FREE(current, allocator_data);
2133      current = next;
2134      }
2135    }
2136    
2137  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
2138  {  {
2139  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 3530  int range_right = -1, range_len = 3 - 1; Line 3550  int range_right = -1, range_len = 3 - 1;
3550  sljit_ub *update_table = NULL;  sljit_ub *update_table = NULL;
3551  BOOL in_range;  BOOL in_range;
3552    
 /* This is even TRUE, if both are NULL. */  
 SLJIT_ASSERT(common->read_only_data_ptr == common->read_only_data);  
   
3553  for (i = 0; i < MAX_N_CHARS; i++)  for (i = 0; i < MAX_N_CHARS; i++)
3554    {    {
3555    chars[i << 1] = NOTACHAR;    chars[i << 1] = NOTACHAR;
# Line 3581  for (i = 0; i <= max; i++) Line 3598  for (i = 0; i <= max; i++)
3598    
3599  if (range_right >= 0)  if (range_right >= 0)
3600    {    {
3601    /* Since no data is consumed (see the assert in the beginning    update_table = (sljit_ub *)allocate_read_only_data(common, 256);
3602    of this function), this space can be reallocated. */    if (update_table == NULL)
   if (common->read_only_data)  
     SLJIT_FREE(common->read_only_data, compiler->allocator_data);  
   
   common->read_only_data_size += 256;  
   common->read_only_data = (sljit_uw *)SLJIT_MALLOC(common->read_only_data_size, compiler->allocator_data);  
   if (common->read_only_data == NULL)  
3603      return TRUE;      return TRUE;
   
   update_table = (sljit_ub *)common->read_only_data;  
   common->read_only_data_ptr = (sljit_uw *)(update_table + 256);  
3604    memset(update_table, IN_UCHARS(range_len), 256);    memset(update_table, IN_UCHARS(range_len), 256);
3605    
3606    for (i = 0; i < range_len; i++)    for (i = 0; i < range_len; i++)
# Line 6989  cc += GET(cc, 1); Line 6997  cc += GET(cc, 1);
6997    
6998  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
6999  if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))
7000    has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF || *matchingpath == OP_FAIL) ? FALSE : TRUE;
7001    
7002  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
7003    opcode = OP_SCOND;    opcode = OP_SCOND;
# Line 7302  if (opcode == OP_COND || opcode == OP_SC Line 7310  if (opcode == OP_COND || opcode == OP_SC
7310            matchingpath = cc;            matchingpath = cc;
7311          }          }
7312      }      }
7313      else if (*matchingpath == OP_FAIL)
7314        {
7315        SLJIT_ASSERT(!has_alternatives);
7316        if (*cc == OP_ALT)
7317          {
7318          matchingpath = cc + 1 + LINK_SIZE;
7319          cc += GET(cc, 1);
7320          }
7321        else
7322          matchingpath = cc;
7323        }
7324    else    else
7325      {      {
7326      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
# Line 8982  else if (has_alternatives) Line 9001  else if (has_alternatives)
9001    if (alt_max > 4)    if (alt_max > 4)
9002      {      {
9003      /* Table jump if alt_max is greater than 4. */      /* Table jump if alt_max is greater than 4. */
9004      next_update_addr = common->read_only_data_ptr;      next_update_addr = allocate_read_only_data(common, alt_max * sizeof(sljit_uw));
9005      common->read_only_data_ptr += alt_max;      if (SLJIT_UNLIKELY(next_update_addr == NULL))
9006          return;
9007      sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr);      sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr);
9008      add_label_addr(common, next_update_addr++);      add_label_addr(common, next_update_addr++);
9009      }      }
# Line 9766  memset(common, 0, sizeof(compiler_common Line 9786  memset(common, 0, sizeof(compiler_common
9786  rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;  rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
9787    
9788  common->start = rootbacktrack.cc;  common->start = rootbacktrack.cc;
9789  common->read_only_data = NULL;  common->read_only_data_head = NULL;
 common->read_only_data_size = 0;  
 common->read_only_data_ptr = NULL;  
9790  common->fcc = tables + fcc_offset;  common->fcc = tables + fcc_offset;
9791  common->lcc = (sljit_sw)(tables + lcc_offset);  common->lcc = (sljit_sw)(tables + lcc_offset);
9792  common->mode = mode;  common->mode = mode;
# Line 9951  if (common->has_then) Line 9969  if (common->has_then)
9969    set_then_offsets(common, common->start, NULL);    set_then_offsets(common, common->start, NULL);
9970    }    }
9971    
 if (common->read_only_data_size > 0)  
   {  
   common->read_only_data = (sljit_uw *)SLJIT_MALLOC(common->read_only_data_size, compiler->allocator_data);  
   if (common->read_only_data == NULL)  
     {  
     SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);  
     SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);  
     return;  
     }  
   common->read_only_data_ptr = common->read_only_data;  
   }  
   
9972  compiler = sljit_create_compiler(NULL);  compiler = sljit_create_compiler(NULL);
9973  if (!compiler)  if (!compiler)
9974    {    {
9975    SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);    SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
9976    SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);    SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
   if (common->read_only_data)  
     SLJIT_FREE(common->read_only_data, compiler->allocator_data);  
9977    return;    return;
9978    }    }
9979  common->compiler = compiler;  common->compiler = compiler;
# Line 10008  if ((re->options & PCRE_ANCHORED) == 0) Line 10012  if ((re->options & PCRE_ANCHORED) == 0)
10012    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
10013      {      {
10014      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))
10015        {        ;
       /* If read_only_data is reallocated, we might have an allocation failure. */  
       if (common->read_only_data_size > 0 && common->read_only_data == NULL)  
         {  
         sljit_free_compiler(compiler);  
         SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);  
         SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);  
         return;  
         }  
       }  
10016      else if ((re->flags & PCRE_FIRSTSET) != 0)      else if ((re->flags & PCRE_FIRSTSET) != 0)
10017        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);
10018      else if ((re->flags & PCRE_STARTLINE) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)
# Line 10070  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 10065  if (SLJIT_UNLIKELY(sljit_get_compiler_er
10065    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
10066    SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);    SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
10067    SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);    SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
10068    if (common->read_only_data)    free_read_only_data(common->read_only_data_head, compiler->allocator_data);
     SLJIT_FREE(common->read_only_data, compiler->allocator_data);  
10069    return;    return;
10070    }    }
10071    
# Line 10111  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 10105  if (SLJIT_UNLIKELY(sljit_get_compiler_er
10105    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
10106    SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);    SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
10107    SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);    SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
10108    if (common->read_only_data)    free_read_only_data(common->read_only_data_head, compiler->allocator_data);
     SLJIT_FREE(common->read_only_data, compiler->allocator_data);  
10109    return;    return;
10110    }    }
10111    
# Line 10192  while (common->currententry != NULL) Line 10185  while (common->currententry != NULL)
10185      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
10186      SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);      SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
10187      SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);      SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
10188      if (common->read_only_data)      free_read_only_data(common->read_only_data_head, compiler->allocator_data);
       SLJIT_FREE(common->read_only_data, compiler->allocator_data);  
10189      return;      return;
10190      }      }
10191    flush_stubs(common);    flush_stubs(common);
# Line 10303  if (common->getucd != NULL) Line 10295  if (common->getucd != NULL)
10295    }    }
10296  #endif  #endif
10297    
 SLJIT_ASSERT(common->read_only_data + (common->read_only_data_size >> SLJIT_WORD_SHIFT) == common->read_only_data_ptr);  
10298  SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);  SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
10299  SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);  SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
10300    
# Line 10318  while (label_addr != NULL) Line 10309  while (label_addr != NULL)
10309  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
10310  if (executable_func == NULL)  if (executable_func == NULL)
10311    {    {
10312    if (common->read_only_data)    free_read_only_data(common->read_only_data_head, compiler->allocator_data);
     SLJIT_FREE(common->read_only_data, compiler->allocator_data);  
10313    return;    return;
10314    }    }
10315    
# Line 10343  else Line 10333  else
10333      /* This case is highly unlikely since we just recently      /* This case is highly unlikely since we just recently
10334      freed a lot of memory. Not impossible though. */      freed a lot of memory. Not impossible though. */
10335      sljit_free_code(executable_func);      sljit_free_code(executable_func);
10336      if (common->read_only_data)      free_read_only_data(common->read_only_data_head, compiler->allocator_data);
       SLJIT_FREE(common->read_only_data, compiler->allocator_data);  
10337      return;      return;
10338      }      }
10339    memset(functions, 0, sizeof(executable_functions));    memset(functions, 0, sizeof(executable_functions));
# Line 10355  else Line 10344  else
10344    }    }
10345    
10346  functions->executable_funcs[mode] = executable_func;  functions->executable_funcs[mode] = executable_func;
10347  functions->read_only_data[mode] = common->read_only_data;  functions->read_only_data_heads[mode] = common->read_only_data_head;
10348  functions->executable_sizes[mode] = executable_size;  functions->executable_sizes[mode] = executable_size;
10349  }  }
10350    
10351  static int jit_machine_stack_exec(jit_arguments *arguments, void *executable_func)  static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, void *executable_func)
10352  {  {
10353  union {  union {
10354     void *executable_func;     void *executable_func;
# Line 10542  for (i = 0; i < JIT_NUMBER_OF_COMPILE_MO Line 10531  for (i = 0; i < JIT_NUMBER_OF_COMPILE_MO
10531    {    {
10532    if (functions->executable_funcs[i] != NULL)    if (functions->executable_funcs[i] != NULL)
10533      sljit_free_code(functions->executable_funcs[i]);      sljit_free_code(functions->executable_funcs[i]);
10534    if (functions->read_only_data[i] != NULL)    free_read_only_data(functions->read_only_data_heads[i], NULL);
     SLJIT_FREE(functions->read_only_data[i], compiler->allocator_data);  
10535    }    }
10536  SLJIT_FREE(functions, compiler->allocator_data);  SLJIT_FREE(functions, compiler->allocator_data);
10537  }  }

Legend:
Removed from v.1508  
changed lines
  Added in v.1533

  ViewVC Help
Powered by ViewVC 1.1.5