• use Jenkins’ one-at-a-time hash for mksh keytabs, as it has

much better avalanche and no known funnels
• improve comments
• fix some types (uint32_t for hash, size_t for sizes)
• optimise ktsort()

no functional change, I think
This commit is contained in:
tg 2009-08-28 18:54:01 +00:00
parent 8f937ec71b
commit ca1f967a45
7 changed files with 63 additions and 55 deletions

6
exec.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.60 2009/08/08 13:08:49 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/exec.c,v 1.61 2009/08/28 18:53:57 tg Exp $");
static int comexec(struct op *, struct tbl *volatile, const char **, static int comexec(struct op *, struct tbl *volatile, const char **,
int volatile, volatile int *); int volatile, volatile int *);
@ -800,7 +800,7 @@ shcomexec(const char **wp)
* is created if none is found. * is created if none is found.
*/ */
struct tbl * struct tbl *
findfunc(const char *name, unsigned int h, int create) findfunc(const char *name, uint32_t h, int create)
{ {
struct block *l; struct block *l;
struct tbl *tp = NULL; struct tbl *tp = NULL;
@ -899,7 +899,7 @@ struct tbl *
findcom(const char *name, int flags) findcom(const char *name, int flags)
{ {
static struct tbl temp; static struct tbl temp;
unsigned int h = hash(name); uint32_t h = hash(name);
struct tbl *tp = NULL, *tbi; struct tbl *tp = NULL, *tbi;
unsigned char insert = Flag(FTRACKALL); /* insert if not found */ unsigned char insert = Flag(FTRACKALL); /* insert if not found */
char *fpath; /* for function autoloading */ char *fpath; /* for function autoloading */

View File

@ -25,7 +25,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.120 2009/08/08 13:08:50 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.121 2009/08/28 18:53:58 tg Exp $");
#if HAVE_KILLPG #if HAVE_KILLPG
/* /*
@ -1130,7 +1130,7 @@ c_alias(const char **wp)
const char *alias = *wp, *val, *newval; const char *alias = *wp, *val, *newval;
char *xalias = NULL; char *xalias = NULL;
struct tbl *ap; struct tbl *ap;
int h; uint32_t h;
if ((val = cstrchr(alias, '='))) { if ((val = cstrchr(alias, '='))) {
strndupx(xalias, alias, val++ - alias, ATEMP); strndupx(xalias, alias, val++ - alias, ATEMP);

4
lex.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.89 2009/07/06 15:06:23 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lex.c,v 1.90 2009/08/28 18:53:58 tg Exp $");
/* /*
* states while lexing word * states while lexing word
@ -909,7 +909,7 @@ yylex(int cf)
if (*ident != '\0' && (cf&(KEYWORD|ALIAS))) { if (*ident != '\0' && (cf&(KEYWORD|ALIAS))) {
struct tbl *p; struct tbl *p;
int h = hash(ident); uint32_t h = hash(ident);
/* { */ /* { */
if ((cf & KEYWORD) && (p = ktsearch(&keywords, ident, h)) && if ((cf & KEYWORD) && (p = ktsearch(&keywords, ident, h)) &&

68
main.c
View File

@ -33,7 +33,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.137 2009/08/08 13:08:51 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.138 2009/08/28 18:53:59 tg Exp $");
extern char **environ; extern char **environ;
@ -148,7 +148,8 @@ main(int argc, const char *argv[])
initkeywords(); initkeywords();
/* define built-in commands */ /* define built-in commands */
ktinit(&builtins, APERM, 64); /* must be 2^n (currently 44 builtins) */ ktinit(&builtins, APERM,
/* must be 80% of 2^n (currently 44 builtins) */ 64);
for (i = 0; mkshbuiltins[i].name != NULL; i++) for (i = 0; mkshbuiltins[i].name != NULL; i++)
builtin(mkshbuiltins[i].name, mkshbuiltins[i].func); builtin(mkshbuiltins[i].name, mkshbuiltins[i].func);
@ -1233,36 +1234,36 @@ maketemp(Area *ap, Temp_type type, struct temp **tlist)
#define INIT_TBLS 8 /* initial table size (power of 2) */ #define INIT_TBLS 8 /* initial table size (power of 2) */
static void texpand(struct table *, int); static void texpand(struct table *, size_t);
static int tnamecmp(const void *, const void *); static int tnamecmp(const void *, const void *);
unsigned int /* Bob Jenkins' one-at-a-time hash */
hash(const char *n) uint32_t
hash(const char *cp)
{ {
unsigned int h = 0; register uint32_t h = 0;
register uint8_t c;
register const uint8_t *bp = (const uint8_t *)cp;
while (*n != '\0') while ((c = *bp++)) {
h = 2*h + *n++; h += c;
return (h * 32821); /* scatter bits */ h += h << 10;
} h ^= h >> 6;
}
void h += h << 3;
ktinit(struct table *tp, Area *ap, int tsize) h ^= h >> 11;
{ h += h << 15;
tp->areap = ap;
tp->tbls = NULL; return (h);
tp->size = tp->nfree = 0;
if (tsize)
texpand(tp, tsize);
} }
static void static void
texpand(struct table *tp, int nsize) texpand(struct table *tp, size_t nsize)
{ {
int i; size_t i, osize = tp->size;
struct tbl *tblp, **p; struct tbl *tblp, **p;
struct tbl **ntblp, **otblp = tp->tbls; struct tbl **ntblp, **otblp = tp->tbls;
int osize = tp->size;
ntblp = alloc(nsize * sizeof(struct tbl *), tp->areap); ntblp = alloc(nsize * sizeof(struct tbl *), tp->areap);
for (i = 0; i < nsize; i++) for (i = 0; i < nsize; i++)
@ -1288,11 +1289,19 @@ texpand(struct table *tp, int nsize)
afree(otblp, tp->areap); afree(otblp, tp->areap);
} }
/* table */ void
/* name to enter */ ktinit(struct table *tp, Area *ap, size_t tsize)
/* hash(n) */ {
tp->areap = ap;
tp->tbls = NULL;
tp->size = tp->nfree = 0;
if (tsize)
texpand(tp, tsize);
}
/* table, name (key) to search for, hash(n) */
struct tbl * struct tbl *
ktsearch(struct table *tp, const char *n, unsigned int h) ktsearch(struct table *tp, const char *n, uint32_t h)
{ {
struct tbl **pp, *p; struct tbl **pp, *p;
@ -1311,11 +1320,9 @@ ktsearch(struct table *tp, const char *n, unsigned int h)
return (NULL); return (NULL);
} }
/* table */ /* table, name (key) to enter, hash(n) */
/* name to enter */
/* hash(n) */
struct tbl * struct tbl *
ktenter(struct table *tp, const char *n, unsigned int h) ktenter(struct table *tp, const char *n, uint32_t h)
{ {
struct tbl **pp, *p; struct tbl **pp, *p;
int len; int len;
@ -1387,7 +1394,8 @@ ktsort(struct table *tp)
p = alloc((tp->size + 1) * sizeof(struct tbl *), ATEMP); p = alloc((tp->size + 1) * sizeof(struct tbl *), ATEMP);
sp = tp->tbls; /* source */ sp = tp->tbls; /* source */
dp = p; /* dest */ dp = p; /* dest */
for (i = 0; i < (size_t)tp->size; i++) i = (size_t)tp->size;
while (i--)
if ((*dp = *sp++) != NULL && (((*dp)->flag & DEFINED) || if ((*dp = *sp++) != NULL && (((*dp)->flag & DEFINED) ||
((*dp)->flag & ARRAY))) ((*dp)->flag & ARRAY)))
dp++; dp++;

12
sh.h
View File

@ -134,7 +134,7 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.323 2009/08/28 18:33:05 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.324 2009/08/28 18:53:59 tg Exp $");
#endif #endif
#define MKSH_VERSION "R39 2009/08/08" #define MKSH_VERSION "R39 2009/08/08"
@ -1371,7 +1371,7 @@ int glob_str(char *, XPtrV *, int);
/* exec.c */ /* exec.c */
int execute(struct op * volatile, volatile int, volatile int * volatile); int execute(struct op * volatile, volatile int, volatile int * volatile);
int shcomexec(const char **); int shcomexec(const char **);
struct tbl *findfunc(const char *, unsigned int, int); struct tbl *findfunc(const char *, uint32_t, int);
int define(const char *, struct op *); int define(const char *, struct op *);
void builtin(const char *, int (*)(const char **)); void builtin(const char *, int (*)(const char **));
struct tbl *findcom(const char *, int); struct tbl *findcom(const char *, int);
@ -1538,10 +1538,10 @@ void coproc_write_close(int);
int coproc_getfd(int, const char **); int coproc_getfd(int, const char **);
void coproc_cleanup(int); void coproc_cleanup(int);
struct temp *maketemp(Area *, Temp_type, struct temp **); struct temp *maketemp(Area *, Temp_type, struct temp **);
unsigned int hash(const char *); uint32_t hash(const char *);
void ktinit(struct table *, Area *, int); void ktinit(struct table *, Area *, size_t);
struct tbl *ktsearch(struct table *, const char *, unsigned int); struct tbl *ktsearch(struct table *, const char *, uint32_t);
struct tbl *ktenter(struct table *, const char *, unsigned int); struct tbl *ktenter(struct table *, const char *, uint32_t);
#define ktdelete(p) do { p->flag = 0; } while (/* CONSTCOND */ 0) #define ktdelete(p) do { p->flag = 0; } while (/* CONSTCOND */ 0)
void ktwalk(struct tstate *, struct table *); void ktwalk(struct tstate *, struct table *);
struct tbl *ktnext(struct tstate *); struct tbl *ktnext(struct tstate *);

11
syn.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.38 2009/06/11 12:42:20 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/syn.c,v 1.39 2009/08/28 18:54:00 tg Exp $");
struct nesting_state { struct nesting_state {
int start_token; /* token than began nesting (eg, FOR) */ int start_token; /* token than began nesting (eg, FOR) */
@ -696,10 +696,10 @@ block(int type, struct op *t1, struct op *t2, char **wp)
return (t); return (t);
} }
const struct tokeninfo { const struct tokeninfo {
const char *name; const char *name;
short val; short val;
short reserved; short reserved;
} tokentab[] = { } tokentab[] = {
/* Reserved words */ /* Reserved words */
{ "if", IF, true }, { "if", IF, true },
@ -739,7 +739,8 @@ initkeywords(void)
struct tokeninfo const *tt; struct tokeninfo const *tt;
struct tbl *p; struct tbl *p;
ktinit(&keywords, APERM, 32); /* must be 2^n (currently 20 keywords) */ ktinit(&keywords, APERM,
/* must be 80% of 2^n (currently 20 keywords) */ 32);
for (tt = tokentab; tt->name; tt++) { for (tt = tokentab; tt->name; tt++) {
if (tt->reserved) { if (tt->reserved) {
p = ktenter(&keywords, tt->name, hash(tt->name)); p = ktenter(&keywords, tt->name, hash(tt->name));

13
var.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.77 2009/08/08 13:08:53 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var.c,v 1.78 2009/08/28 18:54:01 tg Exp $");
/* /*
* Variables * Variables
@ -125,7 +125,8 @@ initvar(void)
int i; int i;
struct tbl *tp; struct tbl *tp;
ktinit(&specials, APERM, 16); /* must be 2^n (currently 12 specials) */ ktinit(&specials, APERM,
/* must be 80% of 2^n (currently 12 specials) */ 16);
for (i = 0; names[i].name; i++) { for (i = 0; names[i].name; i++) {
tp = ktenter(&specials, names[i].name, hash(names[i].name)); tp = ktenter(&specials, names[i].name, hash(names[i].name));
tp->flag = DEFINED|ISSET; tp->flag = DEFINED|ISSET;
@ -171,9 +172,8 @@ global(const char *n)
struct block *l = e->loc; struct block *l = e->loc;
struct tbl *vp; struct tbl *vp;
int c; int c;
unsigned int h;
bool array; bool array;
uint32_t val; uint32_t h, val;
/* Check to see if this is an array */ /* Check to see if this is an array */
n = array_index_calc(n, &array, &val); n = array_index_calc(n, &array, &val);
@ -252,9 +252,8 @@ local(const char *n, bool copy)
{ {
struct block *l = e->loc; struct block *l = e->loc;
struct tbl *vp; struct tbl *vp;
unsigned int h;
bool array; bool array;
uint32_t val; uint32_t h, val;
/* Check to see if this is an array */ /* Check to see if this is an array */
n = array_index_calc(n, &array, &val); n = array_index_calc(n, &array, &val);
@ -889,7 +888,7 @@ makenv(void)
(vp->flag&(ISSET|EXPORT)) == (ISSET|EXPORT)) { (vp->flag&(ISSET|EXPORT)) == (ISSET|EXPORT)) {
struct block *l2; struct block *l2;
struct tbl *vp2; struct tbl *vp2;
unsigned int h = hash(vp->name); uint32_t h = hash(vp->name);
/* unexport any redefined instances */ /* unexport any redefined instances */
for (l2 = l->next; l2 != NULL; l2 = l2->next) { for (l2 = l->next; l2 != NULL; l2 = l2->next) {