include malloc.h
[unix-history] / usr / src / old / dbx / names.c
CommitLineData
2a24676e
DF
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 */
99c5be11 6
2a24676e
DF
7#ifndef lint
8static char sccsid[] = "@(#)names.c 5.1 (Berkeley) %G%";
9#endif not lint
0022c355
ML
10
11static char rcsid[] = "$Header: names.c,v 1.4 84/12/26 10:40:47 linton Exp $";
99c5be11
ML
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
23typedef 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
32struct 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
42private 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
ecdd5e38 50#define CHUNKSIZE 200
99c5be11
ML
51
52typedef struct Namepool {
53 struct Name name[CHUNKSIZE];
54 struct Namepool *prevpool;
55} *Namepool;
56
57private Namepool namepool = nil;
58private Integer nleft = 0;
99c5be11
ML
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
72public Name identname(s, isallocated)
73String s;
74Boolean 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);
ecdd5e38 112 bzero(newpool, sizeof(newpool));
99c5be11
ML
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 */
136match:
137 return n;
138}
139
99c5be11
ML
140/*
141 * Deallocate the name table.
142 */
143
144public names_free()
145{
0022c355
ML
146 Namepool n, m;
147 register integer i;
99c5be11 148
0022c355
ML
149 n = namepool;
150 while (n != nil) {
151 m = n->prevpool;
152 dispose(n);
153 n = m;
154 }
99c5be11 155 for (i = 0; i < HASHTABLESIZE; i++) {
99c5be11
ML
156 nametable[i] = nil;
157 }
158 namepool = nil;
159 nleft = 0;
160}