|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)names.c 5.1 (Berkeley) 5/31/85"; ! 9: #endif not lint ! 10: ! 11: static char rcsid[] = "$Header: names.c,v 1.4 84/12/26 10:40:47 linton Exp $"; ! 12: ! 13: /* ! 14: * Name are the internal representation for identifiers. ! 15: * ! 16: * A hash table is used to map identifiers to names. ! 17: */ ! 18: ! 19: #include "defs.h" ! 20: #include "names.h" ! 21: ! 22: #ifndef public ! 23: typedef struct Name *Name; ! 24: ! 25: /* ! 26: * Inline (for speed) function to return the identifier (string) ! 27: * associated with a name. Because C cannot support both inlines ! 28: * and data hiding at the same time, the Name structure must be ! 29: * publicly visible. It is not used explicitly, however, outside of this file. ! 30: */ ! 31: ! 32: struct Name { ! 33: char *identifier; ! 34: Name chain; ! 35: }; ! 36: ! 37: #define ident(n) ((n == nil) ? "(noname)" : n->identifier) ! 38: #endif ! 39: ! 40: #define HASHTABLESIZE 2997 ! 41: ! 42: private Name nametable[HASHTABLESIZE]; ! 43: ! 44: /* ! 45: * Names are allocated in large chunks to avoid calls to malloc ! 46: * and to cluster names in memory so that tracing hash chains ! 47: * doesn't cause many a page fault. ! 48: */ ! 49: ! 50: #define CHUNKSIZE 200 ! 51: ! 52: typedef struct Namepool { ! 53: struct Name name[CHUNKSIZE]; ! 54: struct Namepool *prevpool; ! 55: } *Namepool; ! 56: ! 57: private Namepool namepool = nil; ! 58: private Integer nleft = 0; ! 59: ! 60: /* ! 61: * Given an identifier, convert it to a name. ! 62: * If it's not in the hash table, then put it there. ! 63: * ! 64: * The second argument specifies whether the string should be copied ! 65: * into newly allocated space if not found. ! 66: * ! 67: * Pardon my use of goto's, but it seemed more efficient and less convoluted ! 68: * than adding a collection of boolean variables. This routine is time ! 69: * critical when starting up the debugger on large programs. ! 70: */ ! 71: ! 72: public Name identname(s, isallocated) ! 73: String s; ! 74: Boolean isallocated; ! 75: { ! 76: register unsigned h; ! 77: register Char *p, *q; ! 78: register Name n; ! 79: register Integer len; ! 80: Namepool newpool; ! 81: ! 82: h = 0; ! 83: for (p = s; *p != '\0'; p++) { ! 84: h = (h << 1) ^ (*p); ! 85: } ! 86: h = h mod HASHTABLESIZE; ! 87: len = p - s; ! 88: n = nametable[h]; ! 89: while (n != nil) { ! 90: p = s; ! 91: q = n->identifier; ! 92: for (;;) { ! 93: if (*p != *q) { ! 94: goto nomatch; ! 95: } else if (*p == '\0') { ! 96: goto match; ! 97: } ! 98: ++p; ! 99: ++q; ! 100: } ! 101: nomatch: ! 102: n = n->chain; ! 103: } ! 104: ! 105: /* ! 106: * Now we know that name hasn't been found (otherwise we'd have jumped ! 107: * down to match), so we allocate a name, store the identifier, and ! 108: * enter it in the hash table. ! 109: */ ! 110: if (nleft <= 0) { ! 111: newpool = new(Namepool); ! 112: bzero(newpool, sizeof(newpool)); ! 113: newpool->prevpool = namepool; ! 114: namepool = newpool; ! 115: nleft = CHUNKSIZE; ! 116: } ! 117: --nleft; ! 118: n = &(namepool->name[nleft]); ! 119: if (isallocated) { ! 120: n->identifier = s; ! 121: } else { ! 122: n->identifier = newarr(char, len + 1); ! 123: p = s; ! 124: q = n->identifier; ! 125: while (*p != '\0') { ! 126: *q++ = *p++; ! 127: } ! 128: *q = '\0'; ! 129: } ! 130: n->chain = nametable[h]; ! 131: nametable[h] = n; ! 132: ! 133: /* ! 134: * The two possibilities (name known versus unknown) rejoin. ! 135: */ ! 136: match: ! 137: return n; ! 138: } ! 139: ! 140: /* ! 141: * Deallocate the name table. ! 142: */ ! 143: ! 144: public names_free() ! 145: { ! 146: Namepool n, m; ! 147: register integer i; ! 148: ! 149: n = namepool; ! 150: while (n != nil) { ! 151: m = n->prevpool; ! 152: dispose(n); ! 153: n = m; ! 154: } ! 155: for (i = 0; i < HASHTABLESIZE; i++) { ! 156: nametable[i] = nil; ! 157: } ! 158: namepool = nil; ! 159: nleft = 0; ! 160: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.