Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/runtime/gc/c-globals-tbl.c
ViewVC logotype

Annotation of /sml/trunk/src/runtime/gc/c-globals-tbl.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (view) (download) (as text)

1 : monnier 2 /* c-globals-tbl.c
2 :     *
3 :     * COPYRIGHT (c) 1992 by AT&T Bell Laboratories.
4 :     *
5 :     * This implements a registry of global C symbols that may be referenced
6 :     * in the ML heap (e.g., references to C functions).
7 :     */
8 :    
9 :     #include "ml-base.h"
10 :     #include "tags.h"
11 :     #include "ml-values.h"
12 :     #include "c-globals-tbl.h"
13 :    
14 :     #define MAKE_EXTERN(index) MAKE_DESC(index, DTAG_extern)
15 :    
16 :     #define HASH_STRING(name, res) { \
17 :     const char *__cp = (name); \
18 :     int __hash = 0, __n; \
19 :     for (; *__cp; __cp++) { \
20 :     __n = (128*__hash) + (unsigned)*__cp; \
21 :     __hash = __n - (8388593 * (__n / 8388593)); \
22 :     } \
23 :     (res) = __hash; \
24 :     }
25 :    
26 :     typedef struct item { /* An item in the Symbol/Addr tables */
27 :     ml_val_t addr; /* The address of the external reference */
28 :     const char *name; /* The name of the reference */
29 :     int stringHash; /* The hash sum of the name */
30 :     struct item *nextSymb; /* The next item the SymbolTable bucket */
31 :     struct item *nextAddr; /* The next item the AddrTable bucket */
32 :     } item_t;
33 :    
34 :     typedef struct item_ref { /* an item in an export table */
35 :     item_t *item;
36 :     int index;
37 :     struct item_ref *next;
38 :     } item_ref_t;
39 :    
40 :     struct export_table { /* A table of C symbols mapping strings to items, */
41 :     /* which is used when loading a heap image. */
42 :     item_ref_t **table;
43 :     int tableSize;
44 :     int numItems;
45 :     item_t **itemMap; /* A map from item #s to items */
46 :     int itemMapSize;
47 :     };
48 :    
49 :     /* hash key to index */
50 :     #define STRHASH_INDEX(h, sz) ((h) & ((sz)-1))
51 :     #define ADDRHASH_INDEX(a, sz) (((Word_t)(a) >> 3) & ((sz)-1))
52 :    
53 :    
54 :     PVT item_t **SymbolTable = NIL(item_t **); /* Maps names to items */
55 :     PVT item_t **AddrTable = NIL(item_t **); /* Maps addresses to items */
56 :     PVT int TableSize = 0; /* The size of the tables; always */
57 :     /* power of 2. */
58 :     PVT int NumSymbols = 0; /* The number of entries in the tables */
59 :    
60 :     /* local routines */
61 :     PVT void GrowTable (export_table_t *tbl);
62 :    
63 :    
64 :     /* RecordCSymbol:
65 :     *
66 :     * Enter a global C symbol into the tables.
67 :     */
68 :     void RecordCSymbol (const char *name, ml_val_t addr)
69 :     {
70 :     int n, i, hash;
71 :     item_t *item, *p;
72 :    
73 :     ASSERT ((((Word_t)addr & ~TAG_boxed) & TAG_desc) == 0);
74 :    
75 :     if (TableSize == NumSymbols) {
76 :     /* double the table size */
77 :     int newTblSz = (TableSize ? 2*TableSize : 64);
78 :     item_t **newSTbl = NEW_VEC(item_t *, newTblSz);
79 :     item_t **newATbl = NEW_VEC(item_t *, newTblSz);
80 :    
81 :     memset ((char *)newSTbl, 0, sizeof(item_t *) * newTblSz);
82 :     memset ((char *)newATbl, 0, sizeof(item_t *) * newTblSz);
83 :    
84 :     for (i = 0; i < TableSize; i++) {
85 :     for (p = SymbolTable[i]; p != NIL(item_t *); ) {
86 :     item = p;
87 :     p = p->nextSymb;
88 :     n = STRHASH_INDEX(item->stringHash, newTblSz);
89 :     item->nextSymb = newSTbl[n];
90 :     newSTbl[n] = item;
91 :     }
92 :     for (p = AddrTable[i]; p != NIL(item_t *); ) {
93 :     item = p;
94 :     p = p->nextAddr;
95 :     n = ADDRHASH_INDEX(item->addr, newTblSz);
96 :     item->nextAddr = newATbl[n];
97 :     newATbl[n] = item;
98 :     }
99 :     }
100 :    
101 :     if (SymbolTable != NIL(item_t **)) {
102 :     FREE (SymbolTable);
103 :     FREE (AddrTable);
104 :     }
105 :     SymbolTable = newSTbl;
106 :     AddrTable = newATbl;
107 :     TableSize = newTblSz;
108 :     }
109 :    
110 :     /* compute the string hash function */
111 :     HASH_STRING(name, hash);
112 :    
113 :     /* Allocate the item */
114 :     item = NEW_OBJ(item_t);
115 :     item->name = name;
116 :     item->stringHash = hash;
117 :     item->addr = addr;
118 :    
119 :     /* insert the item into the symbol table. */
120 :     n = STRHASH_INDEX(hash, TableSize);
121 :     for (p = SymbolTable[n]; p != NIL(item_t *); p = p->nextSymb) {
122 :     if ((p->stringHash == hash) && (strcmp(name, p->name) == 0)) {
123 :     if (p->addr != addr)
124 :     Die ("global C symbol \"%s\" defined twice", name);
125 :     else {
126 :     FREE (item);
127 :     return;
128 :     }
129 :     }
130 :     }
131 :     item->nextSymb = SymbolTable[n];
132 :     SymbolTable[n] = item;
133 :    
134 :     /* insert the item into the addr table. */
135 :     n = ADDRHASH_INDEX(addr, TableSize);
136 :     for (p = AddrTable[n]; p != NIL(item_t *); p = p->nextAddr) {
137 :     if (p->addr == addr) {
138 :     if ((p->stringHash != hash) || (strcmp(name, p->name) != 0))
139 :     Die ("address %#x defined twice: \"%s\" and \"%s\"",
140 :     addr, p->name, name);
141 :     else {
142 :     FREE (item);
143 :     return;
144 :     }
145 :     }
146 :     }
147 :     item->nextAddr = AddrTable[n];
148 :     AddrTable[n] = item;
149 :     NumSymbols++;
150 :    
151 :     } /* end of RecordCSymbol */
152 :    
153 :     /* AddrToCSymbol:
154 :     *
155 :     * Return the name of the C symbol that labels the given address
156 :     * (or NIL).
157 :     */
158 :     const char *AddrToCSymbol (ml_val_t addr)
159 :     {
160 :     item_t *q;
161 :    
162 :     /* Find the symbol in the AddrTable */
163 :     for (q = AddrTable[ADDRHASH_INDEX(addr, TableSize)];
164 :     q != NIL(item_t *);
165 :     q = q->nextAddr)
166 :     {
167 :     if (q->addr == addr)
168 :     return q->name;
169 :     }
170 :    
171 :     return NIL(const char *);
172 :    
173 :     } /* end of AddrToCSymbol */
174 :    
175 :     /* NewExportTbl:
176 :     */
177 :     export_table_t *NewExportTbl ()
178 :     {
179 :     export_table_t *tbl;
180 :    
181 :     tbl = NEW_OBJ(export_table_t);
182 :     tbl->table = NIL(item_ref_t **);
183 :     tbl->tableSize = 0;
184 :     tbl->numItems = 0;
185 :     tbl->itemMap = NIL(item_t **);
186 :     tbl->itemMapSize = 0;
187 :    
188 :     return tbl;
189 :    
190 :     } /* end of NewExportTbl */
191 :    
192 :     /* ExportCSymbol:
193 :     *
194 :     * Add an external address to an export table, returning its external reference
195 :     * descriptor.
196 :     */
197 :     ml_val_t ExportCSymbol (export_table_t *tbl, ml_val_t addr)
198 :     {
199 :     Addr_t a = PTR_MLtoADDR(addr);
200 :     item_ref_t *p;
201 :     item_t *q;
202 :     int h, index;
203 :    
204 :     /*SayDebug("ExportCSymbol: addr = %#x, ", addr);*/
205 :    
206 :     if (tbl->numItems >= tbl->tableSize)
207 :     GrowTable (tbl);
208 :    
209 :     /* First check to see if addr is already in tbl */
210 :     h = ADDRHASH_INDEX(a, tbl->tableSize);
211 :     for (p = tbl->table[h]; p != NIL(item_ref_t *); p = p->next) {
212 :     if (p->item->addr == addr) {
213 :     /*SayDebug("old name = \"%s\", index = %d\n", p->item->name, p->index);*/
214 :     return MAKE_EXTERN(p->index);
215 :     }
216 :     }
217 :    
218 :     /* Find the symbol in the AddrTable */
219 :     for (q = AddrTable[ADDRHASH_INDEX(a, TableSize)]; q != NIL(item_t *); q = q->nextAddr) {
220 :     if (q->addr == addr)
221 :     break;
222 :     }
223 :     if (q == NIL(item_t *)) {
224 :     Error("external address %#x not registered\n", addr);
225 :     return ML_unit;
226 :     }
227 :    
228 :     /* Insert the index into the address to index map. */
229 :     /*SayDebug("new name = \"%s\", index = %d\n", q->name, tbl->numItems);*/
230 :     index = tbl->numItems++;
231 :     if (tbl->itemMapSize <= index) {
232 :     int newSz = ((tbl->itemMapSize == 0) ? 64 : 2*tbl->itemMapSize);
233 :     item_t **newMap = NEW_VEC(item_t *, newSz);
234 :     int i;
235 :    
236 :     for (i = 0; i < tbl->itemMapSize; i++)
237 :     newMap[i] = tbl->itemMap[i];
238 :     if (tbl->itemMap != NIL(item_t **))
239 :     FREE (tbl->itemMap);
240 :     tbl->itemMap = newMap;
241 :     tbl->itemMapSize = newSz;
242 :     }
243 :     tbl->itemMap[index] = q;
244 :    
245 :     /* Insert the address into the export table */
246 :     p = NEW_OBJ(item_ref_t);
247 :     p->item = q;
248 :     p->index = index;
249 :     p->next = tbl->table[h];
250 :     tbl->table[h] = p;
251 :    
252 :     return MAKE_EXTERN(index);
253 :    
254 :     } /* end of ExportCSymbol */
255 :    
256 :     /* AddrOfCSymbol:
257 :     *
258 :     * Given an external reference, return its address.
259 :     */
260 :     ml_val_t AddrOfCSymbol (export_table_t *tbl, ml_val_t xref)
261 :     {
262 :     int index;
263 :    
264 :     index = GET_LEN(xref);
265 :    
266 :     /*SayDebug("AddrOfCSymbol: %#x: %d --> %#x\n", xref, index, tbl->itemMap[index]->addr);*/
267 :     if (index >= tbl->numItems)
268 :     Die ("bad external object index %d", index);
269 :     else
270 :     return tbl->itemMap[index]->addr;
271 :    
272 :     } /* end of AddrOfCSymbol */
273 :    
274 :     /* ExportedSymbols:
275 :     */
276 :     void ExportedSymbols (export_table_t *tbl, int *numSymbs, export_item_t **symbs)
277 :     {
278 :     int i, n = tbl->numItems;
279 :     item_t **p;
280 :     export_item_t *ep;
281 :    
282 :     *numSymbs = n;
283 :     *symbs = ep = NEW_VEC(export_item_t, n);
284 :     for (p = tbl->itemMap, i = 0; i < n; i++) {
285 :     *ep = (*p)->name;
286 :     p++; ep++;
287 :     }
288 :    
289 :     } /* end of ExportedSymbols */
290 :    
291 :    
292 :     /* FreeExportTbl:
293 :     *
294 :     * Free the storage used by a import/export table.
295 :     */
296 :     void FreeExportTbl (export_table_t *tbl)
297 :     {
298 :     int i;
299 :     item_ref_t *p, *q;
300 :    
301 :     for (i = 0; i < tbl->tableSize; i++) {
302 :     for (p = tbl->table[i]; p != NIL(item_ref_t *); ) {
303 :     q = p->next;
304 :     FREE (p);
305 :     p = q;
306 :     }
307 :     }
308 :    
309 :     if (tbl->itemMap != NIL(item_t **))
310 :     FREE (tbl->itemMap);
311 :    
312 :     FREE (tbl);
313 :    
314 :     } /* end of FreeExportTbl */
315 :    
316 :    
317 :     /* ImportCSymbol:
318 :     */
319 :     ml_val_t ImportCSymbol (const char *name)
320 :     {
321 :     int hash, index;
322 :     item_t *p;
323 :    
324 :     HASH_STRING(name, hash);
325 :    
326 :     /* insert the item into the symbol table. */
327 :     index = STRHASH_INDEX(hash, TableSize);
328 :     for (p = SymbolTable[index]; p != NIL(item_t *); p = p->nextSymb) {
329 :     if ((p->stringHash == hash) && (strcmp(name, p->name) == 0)) {
330 :     return (p->addr);
331 :     }
332 :     }
333 :    
334 :     return ML_unit;
335 :    
336 :     } /* end of ImportCSymbol */
337 :    
338 :    
339 :     /* ExportTableSz:
340 :     *
341 :     * Return the number of bytes required to represent the strings in an exported
342 :     * symbols table.
343 :     */
344 :     Addr_t ExportTableSz (export_table_t *tbl)
345 :     {
346 :     int i;
347 :     Addr_t nbytes;
348 :    
349 :     for (nbytes = 0, i = 0; i < tbl->numItems; i++) {
350 :     nbytes += (strlen(tbl->itemMap[i]->name) + 1);
351 :     }
352 :     nbytes = ROUNDUP(nbytes, WORD_SZB);
353 :    
354 :     return nbytes;
355 :    
356 :     } /* end of ExportTableSz */
357 :    
358 :    
359 :     /* GrowTable:
360 :     */
361 :     PVT void GrowTable (export_table_t *tbl)
362 :     {
363 :     int newTblSz = (tbl->tableSize ? 2 * tbl->tableSize : 32);
364 :     item_ref_t **newTbl = NEW_VEC(item_ref_t *, newTblSz);
365 :     int i, n;
366 :     item_ref_t *p, *q;
367 :    
368 :     memset ((char *)newTbl, 0, newTblSz * sizeof(item_ref_t *));
369 :    
370 :     for (i = 0; i < tbl->tableSize; i++) {
371 :     for (p = tbl->table[i]; p != NIL(item_ref_t *); ) {
372 :     q = p;
373 :     p = p->next;
374 :     n = ADDRHASH_INDEX(q->item->addr, newTblSz);
375 :     q->next = newTbl[n];
376 :     newTbl[n] = q;
377 :     }
378 :     }
379 :    
380 :     if (tbl->table != NIL(item_ref_t **)) FREE (tbl->table);
381 :     tbl->table = newTbl;
382 :     tbl->tableSize = newTblSz;
383 :    
384 :     } /* end of GrowTable */
385 :    

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0