makefile_bertw: always compile with -g
[nedit-bw.git] / GlobalSymTable.patch
blob066559b16821704e8da15daef81c2bf300981bb2
1 Subject: Use a hashtable for the global symbols
3 ---
5 source/interpret.c | 137 +++++++++++++++++++++++++++++++++++++----------------
6 source/interpret.h | 1
7 source/interpret.c | 135 +++++++++++++++++++++++++++++++++++++----------------
8 source/interpret.h | 3 -
9 2 files changed, 98 insertions(+), 40 deletions(-)
11 diff --quilt old/source/interpret.c new/source/interpret.c
12 --- old/source/interpret.c
13 +++ new/source/interpret.c
14 @@ -95,7 +95,10 @@ static int callSubroutineFromSymbol(Symb
15 static int concatenateNwithSep(int nVals, const char *sep, char **result,
16 int leaveParams);
17 static int makeArrayKeyFromArgs(int nArgs, char **keyString, int leaveParams);
18 -static void freeSymbolTable(Symbol *symTab);
19 +static void freeSymbolList(Symbol *symList);
20 +static void addToGlobalSymTab(Symbol *sym);
21 +static unsigned int hashNameWith(unsigned int hash, const char *name);
22 +static unsigned int hashName(const char *name);
23 static int errCheck(const char *s);
24 static int execError(const char *s1, const char *s2);
25 static rbTreeNode *arrayEmptyAllocator(void);
26 @@ -138,8 +141,11 @@ static void stackdumpInternal(int n, int
27 #define DISASM_RT(i, n)
28 #endif /* #ifndef DEBUG_STACK */
30 -/* Global symbols and function definitions */
31 -static Symbol *GlobalSymList = NULL;
32 +/* Global symbols and function definitions, is null initialized */
33 +#define GLOBAL_SYMTAB_SHIFT 8
34 +#define GLOBAL_SYMTAB_SIZE (1u << (GLOBAL_SYMTAB_SHIFT))
35 +#define GLOBAL_SYMTAB_MASK ((GLOBAL_SYMTAB_SIZE) - 1)
36 +static Symbol *GlobalSymTab[GLOBAL_SYMTAB_SIZE];
38 /* List of all memory allocated for strings */
39 static char *AllocatedStrings = NULL;
40 @@ -316,7 +322,7 @@ Program *FinishCreatingProgram(Accumulat
41 void FreeProgram(Program *prog)
43 if (--prog->refcount == 0) {
44 - freeSymbolTable(prog->localSymList);
45 + freeSymbolList(prog->localSymList);
46 XtFree((char *)prog->code);
47 XtFree((char *)prog->name);
48 XtFree((char *)prog);
49 @@ -761,14 +767,14 @@ Symbol *InstallMultiAssignExpr(void)
50 ** install an array iteration symbol
51 ** it is tagged as an integer but holds an array node pointer
53 -#define ARRAY_ITER_SYM_PREFIX "aryiter "
54 +#define ARRAY_ITER_SYM_PREFIX "aryiter #"
55 Symbol *InstallIteratorSymbol(void)
57 char symbolName[sizeof(ARRAY_ITER_SYM_PREFIX) + TYPE_INT_STR_SIZE(int)];
58 DataValue value;
59 - static int interatorNameIndex = 0;
60 + static int interatorNameIndex;
62 - sprintf(symbolName, ARRAY_ITER_SYM_PREFIX "#%d", interatorNameIndex);
63 + sprintf(symbolName, ARRAY_ITER_SYM_PREFIX "%d", interatorNameIndex);
64 ++interatorNameIndex;
65 value.tag = INT_TAG;
66 value.val.arrayPtr = NULL;
67 @@ -781,15 +787,19 @@ Symbol *InstallIteratorSymbol(void)
69 Symbol *LookupStringConstSymbol(const char *value)
71 + unsigned int idx;
72 Symbol *s;
74 - for (s = GlobalSymList; s != NULL; s = s->next) {
75 - if (s->type == CONST_SYM &&
76 - s->value.tag == STRING_TAG &&
77 - !strcmp(s->value.val.str.rep, value)) {
78 - return(s);
79 + for (idx = 0; idx < GLOBAL_SYMTAB_SIZE; idx++) {
80 + for (s = GlobalSymTab[idx]; s != NULL; s = s->next) {
81 + if (s->type == CONST_SYM
82 + && s->value.tag == STRING_TAG
83 + && !strcmp(s->value.val.str.rep, value)) {
84 + return(s);
85 + }
89 return(NULL);
92 @@ -812,19 +822,39 @@ Symbol *InstallStringConstSymbol(const c
93 return(InstallSymbol(stringName, CONST_SYM, value));
96 +static Symbol *lookupSymbol(Symbol *symlist, const char *name,
97 + unsigned int hash)
99 + while (NULL != symlist) {
100 + if (hash == symlist->hash && strcmp(symlist->name, name) == 0)
101 + return symlist;
102 + symlist = symlist->next;
105 + return NULL;
109 ** find a symbol in the symbol table
111 Symbol *LookupSymbol(const char *name)
113 + unsigned int hash;
114 Symbol *s;
116 - for (s = LocalSymList; s != NULL; s = s->next)
117 - if (strcmp(s->name, name) == 0)
118 - return s;
119 - for (s = GlobalSymList; s != NULL; s = s->next)
120 - if (strcmp(s->name, name) == 0)
121 - return s;
122 + /* calculate hash for name */
123 + hash = hashName(name);
125 + /* search in local symbols */
126 + s = lookupSymbol(LocalSymList, name, hash);
127 + if (NULL != s)
128 + return s;
130 + /* search in global symbols */
131 + s = lookupSymbol(GlobalSymTab[hash & GLOBAL_SYMTAB_MASK], name, hash);
132 + if (NULL != s)
133 + return s;
135 return NULL;
138 @@ -835,17 +865,17 @@ Symbol *InstallSymbol(const char *name,
140 Symbol *s;
142 - s = (Symbol *)malloc(sizeof(Symbol));
143 - s->name = (char *)malloc(strlen(name)+1); /* +1 for '\0' */
144 + s = XtNew(Symbol);
145 + s->name = (char *)XtMalloc(strlen(name) + 1); /* +1 for '\0' */
146 strcpy(s->name, name);
147 s->type = type;
148 s->value = value;
149 + s->hash = hashName(s->name);
150 if (type == LOCAL_SYM) {
151 s->next = LocalSymList;
152 LocalSymList = s;
153 } else {
154 - s->next = GlobalSymList;
155 - GlobalSymList = s;
156 + addToGlobalSymTab(s);
158 return s;
160 @@ -909,8 +939,7 @@ Symbol *PromoteToGlobal(Symbol *sym)
161 but this symbol has no program attached and ProgramFree() is not NULL
162 pointer safe */
163 sym->type = GLOBAL_SYM;
164 - sym->next = GlobalSymList;
165 - GlobalSymList = sym;
166 + addToGlobalSymTab(sym);
168 return sym;
170 @@ -1133,6 +1162,7 @@ void GarbageCollectStrings(void)
171 SparseArrayEntryWrapper *nextAP, *thisAP;
172 char *p, *next;
173 Symbol *s;
174 + unsigned int idx;
176 /* mark all strings as unreferenced */
177 for (p = AllocatedStrings; p != NULL; p = *((char **)p)) {
178 @@ -1146,15 +1176,17 @@ void GarbageCollectStrings(void)
180 /* Sweep the global symbol list, marking which strings are still
181 referenced */
182 - for (s = GlobalSymList; s != NULL; s = s->next) {
183 - if (s->value.tag == STRING_TAG) {
184 - /* test first because it may be read-only static string */
185 - if (!(*(s->value.val.str.rep - 1))) {
186 - *(s->value.val.str.rep - 1) = 1;
187 + for (idx = 0; idx < GLOBAL_SYMTAB_SIZE; idx++) {
188 + for (s = GlobalSymTab[idx]; s != NULL; s = s->next) {
189 + if (s->value.tag == STRING_TAG) {
190 + /* test first because it may be read-only static string */
191 + if (!(*(s->value.val.str.rep - 1))) {
192 + *(s->value.val.str.rep - 1) = 1;
195 + else if (s->value.tag == ARRAY_TAG) {
196 + MarkArrayContentsAsUsed(s->value.val.arrayPtr);
199 - else if (s->value.tag == ARRAY_TAG) {
200 - MarkArrayContentsAsUsed(s->value.val.arrayPtr);
204 @@ -1221,16 +1253,41 @@ static void restoreContext(RestartData *
205 FocusWindow = context->focusWindow;
208 -static void freeSymbolTable(Symbol *symTab)
209 +static void freeSymbolList(Symbol *symList)
211 Symbol *s;
213 - while(symTab != NULL) {
214 - s = symTab;
215 - free(s->name);
216 - symTab = s->next;
217 - free((char *)s);
218 - }
219 + while (symList != NULL) {
220 + s = symList;
221 + symList = s->next;
222 + XtFree((char *)s->name);
223 + XtFree((char *)s);
227 +static unsigned int hashNameWith(unsigned int hash, const char *name)
229 + while (*name) {
230 + unsigned int c = *name++;
231 + hash = (hash * 16777619u) + c;
234 + return hash;
237 +static unsigned int hashName(const char *name)
239 + return hashNameWith(2166136261u, name);
242 +static void addToGlobalSymTab(Symbol *sym)
244 + unsigned int idx;
246 + idx = sym->hash & GLOBAL_SYMTAB_MASK;
248 + sym->next = GlobalSymTab[idx];
249 + GlobalSymTab[idx] = sym;
252 /* true, if you can pop n values */
253 diff --quilt old/source/interpret.h new/source/interpret.h
254 --- old/source/interpret.h
255 +++ new/source/interpret.h
256 @@ -101,7 +101,8 @@ typedef struct SymbolRec {
257 char *name;
258 enum symTypes type;
259 DataValue value;
260 - struct SymbolRec *next; /* to link to another */
261 + unsigned int hash;
262 + struct SymbolRec *next; /* to link to another */
263 } Symbol;
265 typedef struct ProgramTag {