3 source/interpret.c | 137 +++++++++++++++++++++++++++++++++++++----------------
5 2 files changed, 99 insertions(+), 39 deletions(-)
7 diff --quilt old/source/interpret.c new/source/interpret.c
8 --- old/source/interpret.c
9 +++ new/source/interpret.c
10 @@ -147,7 +147,10 @@ static int namedArg1orN(Boolean isFirst)
11 static int swapTop2(void);
12 static int arrayIndex(void);
13 static int makeArrayKeyFromArgs(int nArgs, char **keyString, int leaveParams);
14 -static void freeSymbolTable(Symbol *symTab);
15 +static void freeSymbolList(Symbol *symList);
16 +static void addToGlobalSymTab(Symbol *sym);
17 +static unsigned int hashNameWith(unsigned int hash, const char *name);
18 +static unsigned int hashName(const char *name);
19 static int errCheck(const char *s);
20 static int execError(const char *s1, const char *s2);
21 static rbTreeNode *arrayEmptyAllocator(void);
22 @@ -193,8 +196,11 @@ static void stackdumpInternal(int n, int
23 #define DISASM_RT(i, n)
24 #endif /* #ifndef DEBUG_STACK */
26 -/* Global symbols and function definitions */
27 -static Symbol *GlobalSymList = NULL;
28 +/* Global symbols and function definitions, is null initialized */
29 +#define GLOBAL_SYMTAB_SHIFT 8
30 +#define GLOBAL_SYMTAB_SIZE (1u << (GLOBAL_SYMTAB_SHIFT))
31 +#define GLOBAL_SYMTAB_MASK ((GLOBAL_SYMTAB_SIZE) - 1)
32 +static Symbol *GlobalSymTab[GLOBAL_SYMTAB_SIZE];
34 /* List of all memory allocated for strings */
35 static char *AllocatedStrings = NULL;
36 @@ -397,7 +403,7 @@ Program *FinishCreatingProgram(const cha
38 void FreeProgram(Program *prog)
40 - freeSymbolTable(prog->localSymList);
41 + freeSymbolList(prog->localSymList);
42 XtFree((char *)prog->code);
44 XtFree((char *)prog->name);
45 @@ -788,14 +794,14 @@ void SetMacroFocusWindow(WindowInfo *win
46 ** install an array iteration symbol
47 ** it is tagged as an integer but holds an array node pointer
49 -#define ARRAY_ITER_SYM_PREFIX "aryiter "
50 +#define ARRAY_ITER_SYM_PREFIX "aryiter #"
51 Symbol *InstallIteratorSymbol(void)
53 char symbolName[sizeof(ARRAY_ITER_SYM_PREFIX) + TYPE_INT_STR_SIZE(int)];
55 - static int interatorNameIndex = 0;
56 + static int interatorNameIndex;
58 - sprintf(symbolName, ARRAY_ITER_SYM_PREFIX "#%d", interatorNameIndex);
59 + sprintf(symbolName, ARRAY_ITER_SYM_PREFIX "%d", interatorNameIndex);
62 value.val.arrayPtr = NULL;
63 @@ -808,50 +814,76 @@ Symbol *InstallIteratorSymbol(void)
65 Symbol *LookupStringConstSymbol(const char *value)
70 - for (s = GlobalSymList; s != NULL; s = s->next) {
71 - if (s->type == CONST_SYM &&
72 - s->value.tag == STRING_TAG &&
73 - !strcmp(s->value.val.str.rep, value)) {
75 + for (idx = 0; idx < GLOBAL_SYMTAB_SIZE; idx++) {
76 + for (s = GlobalSymTab[idx]; s != NULL; s = s->next) {
77 + if (s->type == CONST_SYM
78 + && s->value.tag == STRING_TAG
79 + && !strcmp(s->value.val.str.rep, value)) {
89 ** install string str in the global symbol table with a string name
91 +#define STRING_CONST_SYM_PREFIX "string #"
92 Symbol *InstallStringConstSymbol(const char *str)
94 - static int stringConstIndex = 0;
95 - char stringName[35];
96 + static int stringConstIndex;
97 + char stringName[sizeof(STRING_CONST_SYM_PREFIX) + TYPE_INT_STR_SIZE(int)];
100 Symbol *sym = LookupStringConstSymbol(str);
105 - sprintf(stringName, "string #%d", stringConstIndex++);
106 + sprintf(stringName, STRING_CONST_SYM_PREFIX "%d", stringConstIndex++);
107 value.tag = STRING_TAG;
108 AllocNStringCpy(&value.val.str, str);
109 return(InstallSymbol(stringName, CONST_SYM, value));
112 +static Symbol *lookupSymbol(const Symbol *symlist, const char *name,
115 + while (NULL != symlist) {
116 + if (hash == symlist->hash && strcmp(symlist->name, name) == 0)
118 + symlist = symlist->next;
125 ** find a symbol in the symbol table
127 Symbol *LookupSymbol(const char *name)
132 - for (s = LocalSymList; s != NULL; s = s->next)
133 - if (strcmp(s->name, name) == 0)
135 - for (s = GlobalSymList; s != NULL; s = s->next)
136 - if (strcmp(s->name, name) == 0)
138 + /* calculate hash for name */
139 + hash = hashName(name);
141 + /* search in local symbols */
142 + s = lookupSymbol(LocalSymList, name, hash);
146 + /* search in global symbols */
147 + s = lookupSymbol(GlobalSymTab[hash & GLOBAL_SYMTAB_MASK], name, hash);
154 @@ -868,12 +900,12 @@ Symbol *InstallSymbol(const char *name,
158 + s->hash = hashName(s->name);
159 if (type == LOCAL_SYM) {
160 s->next = LocalSymList;
163 - s->next = GlobalSymList;
165 + addToGlobalSymTab(s);
169 @@ -937,8 +969,7 @@ Symbol *PromoteToGlobal(Symbol *sym)
170 but this symbol has no program attached and ProgramFree() is not NULL
172 sym->type = GLOBAL_SYM;
173 - sym->next = GlobalSymList;
174 - GlobalSymList = sym;
175 + addToGlobalSymTab(sym);
179 @@ -1161,6 +1192,7 @@ void GarbageCollectStrings(void)
180 SparseArrayEntryWrapper *nextAP, *thisAP;
185 /* mark all strings as unreferenced */
186 for (p = AllocatedStrings; p != NULL; p = *((char **)p)) {
187 @@ -1174,15 +1206,17 @@ void GarbageCollectStrings(void)
189 /* Sweep the global symbol list, marking which strings are still
191 - for (s = GlobalSymList; s != NULL; s = s->next) {
192 - if (s->value.tag == STRING_TAG) {
193 - /* test first because it may be read-only static string */
194 - if (!(*(s->value.val.str.rep - 1))) {
195 - *(s->value.val.str.rep - 1) = 1;
196 + for (idx = 0; idx < GLOBAL_SYMTAB_SIZE; idx++) {
197 + for (s = GlobalSymTab[idx]; s != NULL; s = s->next) {
198 + if (s->value.tag == STRING_TAG) {
199 + /* test first because it may be read-only static string */
200 + if (!(*(s->value.val.str.rep - 1))) {
201 + *(s->value.val.str.rep - 1) = 1;
204 + else if (s->value.tag == ARRAY_TAG) {
205 + MarkArrayContentsAsUsed(s->value.val.arrayPtr);
208 - else if (s->value.tag == ARRAY_TAG) {
209 - MarkArrayContentsAsUsed(s->value.val.arrayPtr);
213 @@ -1249,17 +1283,42 @@ static void restoreContext(RestartData *
214 FocusWindow = context->focusWindow;
217 -static void freeSymbolTable(Symbol *symTab)
218 +static void freeSymbolList(Symbol *symList)
222 - while(symTab != NULL) {
225 + while (symList != NULL) {
232 +static unsigned int hashNameWith(unsigned int hash, const char *name)
235 + unsigned char c = *name++;
236 + hash = (hash * 16777619u) + c;
242 +static unsigned int hashName(const char *name)
244 + return hashNameWith(2166136261u, name);
247 +static void addToGlobalSymTab(Symbol *sym)
251 + idx = sym->hash & GLOBAL_SYMTAB_MASK;
253 + sym->next = GlobalSymTab[idx];
254 + GlobalSymTab[idx] = sym;
257 #define POP(dataVal) \
260 @@ -4448,8 +4507,8 @@ static void disasmInternal(Inst *inst, i
261 if (j == OP_PUSH_SYM || j == OP_ASSIGN) {
262 Symbol *sym = inst[i+1].sym;
263 printd(" %s", sym->name);
264 - if (sym->value.tag == STRING_TAG &&
265 - strncmp(sym->name, "string #", 8) == 0) {
266 + if (sym->type == CONST_SYM
267 + && sym->value.tag == STRING_TAG) {
271 diff --quilt old/source/interpret.h new/source/interpret.h
272 --- old/source/interpret.h
273 +++ new/source/interpret.h
274 @@ -111,6 +111,7 @@ typedef struct SymbolRec {
279 struct SymbolRec *next; /* to link to another */