convert GlobalSymList to hash table
[nedit-bw.git] / GlobalSymTable.patch
blob51b14516a43559d7150434e6e49b997fa0286ace
1 ---
3 source/interpret.c | 136 ++++++++++++++++++++++++++++++++++++++---------------
4 source/interpret.h | 1
5 2 files changed, 100 insertions(+), 37 deletions(-)
7 diff --quilt old/source/interpret.c new/source/interpret.c
8 --- old/source/interpret.c
9 +++ new/source/interpret.c
10 @@ -145,11 +145,17 @@ static int namedArg1(void);
11 static int namedArgN(void);
12 static int namedArg1orN(Boolean isFirst);
13 static int swapTop2(void);
14 static int arrayIndex(void);
15 static int makeArrayKeyFromArgs(int nArgs, char **keyString, int leaveParams);
16 -static void freeSymbolTable(Symbol *symTab);
17 +static void freeSymbolList(Symbol *symList);
18 +static void addToSymTab(Symbol **symTab, unsigned int symTabSize,
19 + Symbol *sym);
20 +static Symbol *lookUpInSymTab(Symbol **symTab, unsigned int symTabSize,
21 + const char *name);
22 +static unsigned int hashNameWith(unsigned int hash, const char *name);
23 +static unsigned int hashName(const char *name);
24 static int errCheck(const char *s);
25 static int execError(const char *s1, const char *s2);
26 static rbTreeNode *arrayEmptyAllocator(void);
27 static rbTreeNode *arrayAllocateNode(rbTreeNode *src);
28 static int arrayEntryCopyToNode(rbTreeNode *dst, rbTreeNode *src);
29 @@ -191,12 +197,13 @@ static void stackdumpInternal(int n, int
30 #else /* #ifndef DEBUG_STACK */
31 #define STACKDUMP(n, x)
32 #define DISASM_RT(i, n)
33 #endif /* #ifndef DEBUG_STACK */
35 -/* Global symbols and function definitions */
36 -static Symbol *GlobalSymList = NULL;
37 +/* Global symbols and function definitions, is null initialized */
38 +#define GLOBAL_SYMTAB_SIZE 256u
39 +static Symbol *GlobalSymTab[GLOBAL_SYMTAB_SIZE];
41 /* List of all memory allocated for strings */
42 static char *AllocatedStrings = NULL;
44 typedef struct SparseArrayEntryWrapperTag {
45 @@ -395,11 +402,11 @@ Program *FinishCreatingProgram(const cha
46 return newProg;
49 void FreeProgram(Program *prog)
51 - freeSymbolTable(prog->localSymList);
52 + freeSymbolList(prog->localSymList);
53 XtFree((char *)prog->code);
54 if (prog->name) {
55 XtFree((char *)prog->name);
57 XtFree((char *)prog);
58 @@ -789,18 +796,18 @@ void SetMacroFocusWindow(WindowInfo *win
61 ** install an array iteration symbol
62 ** it is tagged as an integer but holds an array node pointer
64 -#define ARRAY_ITER_SYM_PREFIX "aryiter "
65 +#define ARRAY_ITER_SYM_PREFIX "aryiter #"
66 Symbol *InstallIteratorSymbol(void)
68 char symbolName[sizeof(ARRAY_ITER_SYM_PREFIX) + TYPE_INT_STR_SIZE(int)];
69 DataValue value;
70 - static int interatorNameIndex = 0;
71 + static int interatorNameIndex;
73 - sprintf(symbolName, ARRAY_ITER_SYM_PREFIX "#%d", interatorNameIndex);
74 + sprintf(symbolName, ARRAY_ITER_SYM_PREFIX "%d", interatorNameIndex);
75 ++interatorNameIndex;
76 value.tag = INT_TAG;
77 value.val.arrayPtr = NULL;
78 return(InstallSymbol(symbolName, LOCAL_SYM, value));
80 @@ -809,36 +816,42 @@ Symbol *InstallIteratorSymbol(void)
81 ** Lookup a constant string by its value. This allows reuse of string
82 ** constants and fixing a leak in the interpreter.
84 Symbol *LookupStringConstSymbol(const char *value)
86 + unsigned int idx;
87 Symbol *s;
89 - for (s = GlobalSymList; s != NULL; s = s->next) {
90 - if (s->type == CONST_SYM &&
91 - s->value.tag == STRING_TAG &&
92 - !strcmp(s->value.val.str.rep, value)) {
93 - return(s);
94 + for (idx = 0; idx < GLOBAL_SYMTAB_SIZE; idx++) {
95 + for (s = GlobalSymTab[idx]; s != NULL; s = s->next) {
96 + if (s->type == CONST_SYM
97 + && s->value.tag == STRING_TAG
98 + && !strcmp(s->value.val.str.rep, value)) {
99 + return(s);
104 return(NULL);
108 ** install string str in the global symbol table with a string name
110 +#define STRING_CONST_SYM_PREFIX "string #"
111 Symbol *InstallStringConstSymbol(const char *str)
113 - static int stringConstIndex = 0;
114 - char stringName[35];
115 + static int stringConstIndex;
116 + char stringName[sizeof(STRING_CONST_SYM_PREFIX) + TYPE_INT_STR_SIZE(int)];
117 DataValue value;
119 Symbol *sym = LookupStringConstSymbol(str);
120 if (sym) {
121 return sym;
124 - sprintf(stringName, "string #%d", stringConstIndex++);
125 + sprintf(stringName, STRING_CONST_SYM_PREFIX "%d", stringConstIndex++);
126 value.tag = STRING_TAG;
127 AllocNStringCpy(&value.val.str, str);
128 return(InstallSymbol(stringName, CONST_SYM, value));
131 @@ -850,14 +863,12 @@ Symbol *LookupSymbol(const char *name)
132 Symbol *s;
134 for (s = LocalSymList; s != NULL; s = s->next)
135 if (strcmp(s->name, name) == 0)
136 return s;
137 - for (s = GlobalSymList; s != NULL; s = s->next)
138 - if (strcmp(s->name, name) == 0)
139 - return s;
140 - return NULL;
142 + return lookUpInSymTab(GlobalSymTab, GLOBAL_SYMTAB_SIZE, name);
146 ** install symbol name in symbol table
148 @@ -873,12 +884,11 @@ Symbol *InstallSymbol(const char *name,
149 s->added = 0;
150 if (type == LOCAL_SYM) {
151 s->next = LocalSymList;
152 LocalSymList = s;
153 } else {
154 - s->next = GlobalSymList;
155 - GlobalSymList = s;
156 + addToSymTab(GlobalSymTab, GLOBAL_SYMTAB_SIZE, s);
158 return s;
162 @@ -907,12 +917,11 @@ Symbol *PromoteToGlobal(Symbol *sym)
163 s = LookupSymbol(sym->name);
164 if (s != NULL)
165 return s;
167 sym->type = GLOBAL_SYM;
168 - sym->next = GlobalSymList;
169 - GlobalSymList = sym;
170 + addToSymTab(GlobalSymTab, GLOBAL_SYMTAB_SIZE, sym);
172 return sym;
176 @@ -1131,10 +1140,11 @@ static void MarkArrayContentsAsUsed(Spar
177 void GarbageCollectStrings(void)
179 SparseArrayEntryWrapper *nextAP, *thisAP;
180 char *p, *next;
181 Symbol *s;
182 + unsigned int idx;
184 /* mark all strings as unreferenced */
185 for (p = AllocatedStrings; p != NULL; p = *((char **)p)) {
186 *(p + sizeof(char *)) = 0;
188 @@ -1144,19 +1154,21 @@ void GarbageCollectStrings(void)
189 thisAP->inUse = 0;
192 /* Sweep the global symbol list, marking which strings are still
193 referenced */
194 - for (s = GlobalSymList; s != NULL; s = s->next) {
195 - if (s->value.tag == STRING_TAG) {
196 - /* test first because it may be read-only static string */
197 - if (!(*(s->value.val.str.rep - 1))) {
198 - *(s->value.val.str.rep - 1) = 1;
199 + for (idx = 0; idx < GLOBAL_SYMTAB_SIZE; idx++) {
200 + for (s = GlobalSymTab[idx]; s != NULL; s = s->next) {
201 + if (s->value.tag == STRING_TAG) {
202 + /* test first because it may be read-only static string */
203 + if (!(*(s->value.val.str.rep - 1))) {
204 + *(s->value.val.str.rep - 1) = 1;
207 + else if (s->value.tag == ARRAY_TAG) {
208 + MarkArrayContentsAsUsed(s->value.val.arrayPtr);
211 - else if (s->value.tag == ARRAY_TAG) {
212 - MarkArrayContentsAsUsed(s->value.val.arrayPtr);
216 /* Collect all of the strings which remain unreferenced */
217 next = AllocatedStrings;
218 @@ -1219,21 +1231,71 @@ static void restoreContext(RestartData *
219 PC = context->pc;
220 InitiatingWindow = context->runWindow;
221 FocusWindow = context->focusWindow;
224 -static void freeSymbolTable(Symbol *symTab)
225 +static void freeSymbolList(Symbol *symList)
227 Symbol *s;
229 - while(symTab != NULL) {
230 - s = symTab;
231 - symTab = s->next;
232 + while (symList != NULL) {
233 + s = symList;
234 + symList = s->next;
235 free(s);
239 +static unsigned int hashNameWith(unsigned int hash, const char *name)
241 + while (*name) {
242 + unsigned char c = *name++;
243 + hash = (hash * 16777619u) + c;
246 + return hash;
249 +static unsigned int hashName(const char *name)
251 + return hashNameWith(2166136261u, name);
254 +static void addToSymTab(Symbol **symTab, unsigned int symTabSize,
255 + Symbol *sym)
257 + unsigned int idx;
259 + sym->hash = hashName(sym->name);
261 + idx = sym->hash % symTabSize;
263 + sym->next = symTab[idx];
264 + symTab[idx] = sym;
267 +static Symbol *lookUpInSymTab(Symbol **symTab, unsigned int symTabSize,
268 + const char *name)
270 + unsigned int hash;
271 + unsigned int idx;
272 + Symbol *sym;
274 + hash = hashName(name);
276 + idx = hash % symTabSize;
278 + sym = symTab[idx];
279 + while (sym) {
280 + if (sym->hash == hash && !strcmp(name, sym->name)) {
281 + break;
283 + sym = sym->next;
286 + return sym;
289 #define POP(dataVal) \
290 do { \
291 POP_CHECK(1); \
292 dataVal = *--StackP; \
293 } while (0)
294 @@ -4417,12 +4479,12 @@ static void disasmInternal(Inst *inst, i
295 if (inst[i].func == OpFns[j]) {
296 printd(" %*s", (int)opLen, opNames[j]);
297 if (j == OP_PUSH_SYM || j == OP_ASSIGN) {
298 Symbol *sym = inst[i+1].sym;
299 printd(" %s", sym->name);
300 - if (sym->value.tag == STRING_TAG &&
301 - strncmp(sym->name, "string #", 8) == 0) {
302 + if (sym->type == CONST_SYM
303 + && sym->value.tag == STRING_TAG) {
304 printd(" ");
305 dumpVal(sym->value);
307 ++i;
309 diff --quilt old/source/interpret.h new/source/interpret.h
310 --- old/source/interpret.h
311 +++ new/source/interpret.h
312 @@ -109,10 +109,11 @@ typedef struct SparseArrayEntryTag {
313 /* symbol table entry */
314 typedef struct SymbolRec {
315 enum symTypes type;
316 DataValue value;
317 int added;
318 + unsigned int hash;
319 struct SymbolRec *next; /* to link to another */
320 char name[1];
321 } Symbol;
323 typedef struct ProgramTag {