/* Copyright (c) 1982 Regents of the University of California */
static char sccsid
[] = "@(#)names.c 1.5 (Berkeley) %G%";
static char rcsid
[] = "$Header: names.c,v 1.4 84/12/26 10:40:47 linton Exp $";
* Name are the internal representation for identifiers.
* A hash table is used to map identifiers to names.
typedef struct Name
*Name
;
* Inline (for speed) function to return the identifier (string)
* associated with a name. Because C cannot support both inlines
* and data hiding at the same time, the Name structure must be
* publicly visible. It is not used explicitly, however, outside of this file.
#define ident(n) ((n == nil) ? "(noname)" : n->identifier)
#define HASHTABLESIZE 2997
private Name nametable
[HASHTABLESIZE
];
* Names are allocated in large chunks to avoid calls to malloc
* and to cluster names in memory so that tracing hash chains
* doesn't cause many a page fault.
typedef struct Namepool
{
struct Name name
[CHUNKSIZE
];
struct Namepool
*prevpool
;
private Namepool namepool
= nil
;
private Integer nleft
= 0;
* Given an identifier, convert it to a name.
* If it's not in the hash table, then put it there.
* The second argument specifies whether the string should be copied
* into newly allocated space if not found.
* Pardon my use of goto's, but it seemed more efficient and less convoluted
* than adding a collection of boolean variables. This routine is time
* critical when starting up the debugger on large programs.
public Name
identname(s
, isallocated
)
for (p
= s
; *p
!= '\0'; p
++) {
* Now we know that name hasn't been found (otherwise we'd have jumped
* down to match), so we allocate a name, store the identifier, and
* enter it in the hash table.
bzero(newpool
, sizeof(newpool
));
newpool
->prevpool
= namepool
;
n
= &(namepool
->name
[nleft
]);
n
->identifier
= newarr(char, len
+ 1);
* The two possibilities (name known versus unknown) rejoin.
* Deallocate the name table.
for (i
= 0; i
< HASHTABLESIZE
; i
++) {