Ignore:
Timestamp:
Oct 11, 2008, 9:12:10 AM (17 years ago)
Author:
bird
Message:

kmk: more length optimizations.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/function.c

    r1809 r1827  
    323323
    324324
    325 #ifdef CONFIG_WITH_OPTIMIZATION_HACKS
     325#if defined (CONFIG_WITH_OPTIMIZATION_HACKS) || defined (CONFIG_WITH_VALUE_LENGTH)
    326326/* The maximum length of a function, once reached there is
    327327   it can't be function and we can skip the hash lookup drop out. */
    328328
    329 # ifdef KMK
    330 #  define MAX_FUNCTION_LENGTH 12
    331 # else
    332 #  define MAX_FUNCTION_LENGTH 10
    333 # endif
    334 #endif /* CONFIG_WITH_OPTIMIZATION_HACKS */
     329# define MAX_FUNCTION_LENGTH 12
     330# define MIN_FUNCTION_LENGTH 2
     331
     332/* char map containing the valid function name characters. */
     333static char func_char_map[256];
     334
     335/* Do the hash table lookup. */
     336
     337__inline static const struct function_table_entry *
     338lookup_function_in_hash_tab (const char *s, unsigned char len)
     339{
     340    struct function_table_entry function_table_entry_key;
     341    function_table_entry_key.name = s;
     342    function_table_entry_key.len = len;
     343
     344    return hash_find_item (&function_table, &function_table_entry_key);
     345}
    335346
    336347/* Look up a function by name.  */
    337348
    338 #ifdef CONFIG_WITH_OPTIMIZATION_HACKS
    339 __inline
    340 #endif /* CONFIG_WITH_OPTIMIZATION_HACKS */
     349__inline static const struct function_table_entry *
     350lookup_function (const char *s, unsigned int len)
     351{
     352  unsigned char ch;
     353# if 0 /* insane loop unroll */
     354
     355  if (len > MAX_FUNCTION_LENGTH)
     356      len = MAX_FUNCTION_LENGTH + 1;
     357
     358#  define X(idx) \
     359        if (!func_char_map[ch = s[idx]]) \
     360          { \
     361            if (isblank (ch)) \
     362              return lookup_function_in_hash_tab (s, idx); \
     363            return 0; \
     364          }
     365#  define Z(idx) \
     366        return lookup_function_in_hash_tab (s, idx);
     367
     368  switch (len)
     369    {
     370      default:
     371        assert (0);
     372      case  0: return 0;
     373      case  1: return 0;
     374      case  2: X(0); X(1); Z(2);
     375      case  3: X(0); X(1); X(2); Z(3);
     376      case  4: X(0); X(1); X(2); X(3); Z(4);
     377      case  5: X(0); X(1); X(2); X(3); X(4); Z(5);
     378      case  6: X(0); X(1); X(2); X(3); X(4); X(5); Z(6);
     379      case  7: X(0); X(1); X(2); X(3); X(4); X(5); X(6); Z(7);
     380      case  8: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); Z(8);
     381      case  9: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); Z(9);
     382      case 10: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); X(9); Z(10);
     383      case 11: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); X(9); X(10); Z(11);
     384      case 12: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); X(9); X(10); X(11); Z(12);
     385      case 13: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); X(9); X(10); X(11); X(12);
     386        if ((ch = s[12]) == '\0' || isblank (ch))
     387          return lookup_function_in_hash_tab (s, 12);
     388        return 0;
     389    }
     390#  undef Z
     391#  undef X
     392
     393# else   /* normal loop */
     394  const char *e = s;
     395  if (len > MAX_FUNCTION_LENGTH)
     396      len = MAX_FUNCTION_LENGTH;
     397  while (func_char_map[ch = *e])
     398    {
     399      if (!len--)
     400        return 0;
     401      e++;
     402    }
     403  if (ch == '\0' || isblank ((unsigned char) ch))
     404    return lookup_function_in_hash_tab (s, e - s);
     405  return 0;
     406# endif /* normal loop */
     407}
     408
     409#else  /* original code */
     410/* Look up a function by name.  */
     411
    341412static const struct function_table_entry *
    342413lookup_function (const char *s)
    343414{
    344415  const char *e = s;
    345 #ifdef CONFIG_WITH_OPTIMIZATION_HACKS
    346   int left = MAX_FUNCTION_LENGTH;
    347   int ch;
    348   while (((ch = *e) >= 'a' && ch <='z') || ch == '-')
    349     {
    350       if (!left--)
    351         return 0;
    352       e++;
    353     }
    354 #else
    355416  while (*e && ( (*e >= 'a' && *e <= 'z') || *e == '-'))
    356417    e++;
    357 #endif
    358418  if (*e == '\0' || isblank ((unsigned char) *e))
    359419    {
     
    366426  return 0;
    367427}
     428#endif /* original code */
    368429
    369430
     
    15121573  install_variable_buffer (&buf, &len);
    15131574
     1575#ifndef CONFIG_WITH_VALUE_LENGTH
    15141576  eval_buffer (argv[0]);
     1577#else
     1578  eval_buffer (argv[0], strchr (argv[0], '\0'));
     1579#endif
    15151580
    15161581  restore_variable_buffer (buf, len);
     
    15361601  push_new_variable_scope ();
    15371602
    1538   eval_buffer (argv[0]);
     1603  eval_buffer (argv[0], strchr (argv[0], '\0'));
    15391604
    15401605  pop_variable_scope ();
     
    15651630
    15661631      off = o - variable_buffer;
    1567       o = variable_buffer_output (o, v->value, v->value_length + 1);
     1632      variable_buffer_output (o, v->value, v->value_length + 1);
    15681633      o = variable_buffer + off;
    1569       assert (!o[v->value_length]);
    15701634
    15711635      /* Eval the value.  Pop the current variable buffer setting so that the
     
    15791643        reading_file = &v->fileinfo;
    15801644
    1581       eval_buffer (o);
     1645      assert (!o[v->value_length]);
     1646      eval_buffer (o, o + v->value_length);
    15821647
    15831648      reading_file = reading_file_saved;
     
    16011666#ifdef CONFIG_WITH_VALUE_LENGTH
    16021667    o = variable_buffer_output (o, v->value,
    1603                                 v->value_length >= 0 ? v->value_length : strlen(v->value));
     1668                                v->value_length >= 0
     1669                                ? (unsigned int)v->value_length /* FIXME */
     1670                                : strlen(v->value));
    16041671#else
    16051672    o = variable_buffer_output (o, v->value, strlen(v->value));
     
    30613128                  const char *src = comp;
    30623129                  const char *end = strchr (comp, PATH_SEPARATOR_CHAR);
    3063                   size_t comp_len = end ? end - comp : strlen (comp);
     3130                  size_t comp_len = end ? (size_t)(end - comp) : strlen (comp);
    30643131                  if (!comp_len)
    30653132                    {
     
    41974264}
    41984265
    4199 int
    4200 handle_function (char **op, const char **stringp) /* bird split it up */
     4266
     4267int  /* bird split it up */
     4268#ifndef CONFIG_WITH_VALUE_LENGTH
     4269handle_function (char **op, const char **stringp)
    42014270{
    42024271  const struct function_table_entry *entry_p = lookup_function (*stringp + 1);
     
    42054274  return handle_function2 (entry_p, op, stringp);
    42064275}
     4276#else  /* CONFIG_WITH_VALUE_LENGTH */
     4277handle_function (char **op, const char **stringp, const char *eol)
     4278{
     4279  const char *fname = *stringp + 1;
     4280  const struct function_table_entry *entry_p = lookup_function (fname, eol - fname);
     4281  if (!entry_p)
     4282    return 0;
     4283  return handle_function2 (entry_p, op, stringp);
     4284}
     4285#endif /* CONFIG_WITH_VALUE_LENGTH */
    42074286
    42084287
     
    42464325  /* Are we invoking a builtin function?  */
    42474326
     4327#ifndef CONFIG_WITH_VALUE_LENGTH
    42484328  entry_p = lookup_function (fname);
     4329#else
     4330  entry_p = lookup_function (fname, cp - fname + 1);
     4331#endif
    42494332  if (entry_p)
    42504333    {
     
    42954378      char num[11];
    42964379
     4380#ifndef CONFIG_WITH_VALUE_LENGTH
    42974381      sprintf (num, "%d", i);
    42984382      define_variable (num, strlen (num), "", o_automatic, 0);
     4383#else
     4384      define_variable (num, sprintf (num, "%d", i), "", o_automatic, 0);
     4385#endif
    42994386    }
    43004387
     
    43244411    {
    43254412      const struct floc *reading_file_saved = reading_file;
     4413      char *eos;
    43264414
    43274415      if (!strcmp (funcname, "evalcall"))
     
    43314419
    43324420          size_t off = o - variable_buffer;
    4333           o = variable_buffer_output (o, v->value, v->value_length + 1);
     4421          eos = variable_buffer_output (o, v->value, v->value_length + 1) - 1;
    43344422          o = variable_buffer + off;
    43354423          if (v->fileinfo.filenm)
     
    43414429
    43424430          v->exp_count = EXP_COUNT_MAX;
    4343           o = variable_expand_string (o, body, flen+3);
     4431          o = variable_expand_string_2 (o, body, flen+3, &eos);
    43444432          v->exp_count = 0;
    43454433        }
    43464434
    43474435      install_variable_buffer (&buf, &len);
    4348       eval_buffer (o);
     4436      eval_buffer (o, eos);
    43494437      restore_variable_buffer (buf, len);
    43504438      reading_file = reading_file_saved;
     
    43674455  hash_load (&function_table, function_table_init,
    43684456             FUNCTION_TABLE_ENTRIES, sizeof (struct function_table_entry));
    4369 #ifdef CONFIG_WITH_OPTIMIZATION_HACKS
     4457#if defined (CONFIG_WITH_OPTIMIZATION_HACKS) || defined (CONFIG_WITH_VALUE_LENGTH)
    43704458  {
    4371     unsigned i;
     4459    unsigned int i;
     4460    for (i = 'a'; i <= 'z'; i++)
     4461      func_char_map[i] = 1;
     4462    func_char_map[(unsigned int)'-'] = 1;
     4463
    43724464    for (i = 0; i < FUNCTION_TABLE_ENTRIES; i++)
     4465      {
    43734466        assert (function_table_init[i].len <= MAX_FUNCTION_LENGTH);
     4467        assert (function_table_init[i].len >= MIN_FUNCTION_LENGTH);
     4468      }
    43744469  }
    43754470#endif
Note: See TracChangeset for help on using the changeset viewer.