xref: /plan9/sys/src/cmd/gs/src/inamedef.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1989, 1995, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: inamedef.h,v 1.5 2002/06/16 04:47:10 lpd Exp $ */
18 /* Name table definition */
19 
20 #ifndef inamedef_INCLUDED
21 #  define inamedef_INCLUDED
22 
23 #include "inameidx.h"
24 #include "inamestr.h"
25 #include "inames.h"
26 #include "gsstruct.h"		/* for gc_state_t */
27 
28 /*
29  * The name table machinery has two slightly different configurations:
30  * a faster one that limits the total number of names to 64K and allows
31  * names up to 16K in size, and a slightly slower one that limits
32  * the total to 4M and restricts names to 256 characters.
33  * The maximum number of names is 2^(16+EXTEND_NAMES)-1.
34  */
35 #define max_name_extension_bits 6
36 #if EXTEND_NAMES > max_name_extension_bits
37 #  undef EXTEND_NAMES
38 #  define EXTEND_NAMES max_name_extension_bits
39 #endif
40 /*
41  * We capture the small algorithmic differences between these two
42  * configurations entirely in this header file;
43  * the implementation doesn't need any conditionals on EXTEND_NAMES.
44  */
45 #define max_name_index (uint)((0x10000 << EXTEND_NAMES) - 1)
46 /* As explained below, we distinguish name indices from name counts. */
47 #define max_name_count max_name_index
48 
49 /* ---------------- Structure definitions ---------------- */
50 
51 /*
52  * Define the structure of a name.  The pvalue member implements an
53  * important optimization to avoid lookup for operator and other global
54  * names.
55  */
56 struct name_s {
57 /* pvalue specifies the definition status of the name: */
58 /*      pvalue == pv_no_defn: no definitions */
59 #define pv_no_defn ((ref *)0)
60 /*      pvalue == pv_other: other status */
61 #define pv_other ((ref *)1)
62 /*      pvalue != pv_no_defn, pvalue != pv_other: pvalue is valid */
63 #define pv_valid(pvalue) ((unsigned long)(pvalue) > 1)
64     ref *pvalue;		/* if only defined in systemdict or */
65 				/* userdict, this points to the value */
66 };
67 
68 /*typedef struct name_s name; *//* in iref.h */
69 
70 /*
71  * Define the structure of a name table.  Normally we would make this
72  * an opaque type, but we want to be able to in-line some of the
73  * access procedures.
74  *
75  * The name table is a two-level indexed table, consisting of
76  * sub-tables of size nt_sub_size each.
77  *
78  * First we define the name sub-table structure.
79  */
80 #define nt_log2_sub_size NT_LOG2_SUB_SIZE /* in inameidx.h */
81 # define nt_sub_size (1 << nt_log2_sub_size)
82 # define nt_sub_index_mask (nt_sub_size - 1)
83 typedef struct name_sub_table_s {
84     name names[NT_SUB_SIZE];	/* must be first */
85 #ifdef EXTEND_NAMES
86     uint high_index;		/* sub-table base index & (-1 << 16) */
87 #endif
88 } name_sub_table;
89 
90 /*
91  * Now define the name table itself.
92  * This must be made visible so that the interpreter can use the
93  * inline macros defined below.
94  */
95 struct name_table_s {
96     uint free;			/* head of free list, which is sorted in */
97 				/* increasing count (not index) order */
98     uint sub_next;		/* index of next sub-table to allocate */
99 				/* if not already allocated */
100     uint perm_count;		/* # of permanent (read-only) strings */
101     uint sub_count;		/* index of highest allocated sub-table +1 */
102     uint max_sub_count;		/* max allowable value of sub_count */
103     uint name_string_attrs;	/* imemory_space(memory) | a_readonly */
104     gs_memory_t *memory;
105     uint hash[NT_HASH_SIZE];
106     struct sub_ {		/* both ptrs are 0 or both are non-0 */
107 	name_sub_table *names;
108 	name_string_sub_table_t *strings;
109     } sub[max_name_index / nt_sub_size + 1];
110 };
111 /*typedef struct name_table_s name_table; *//* in inames.h */
112 
113 /* ---------------- Procedural interface ---------------- */
114 
115 /*
116  * Convert between names, indices, and strings.  Note that the inline
117  * versions, but not the procedure versions, take a name_table argument.
118  */
119 		/* index => string */
120 #define names_index_string_inline(nt, nidx)\
121   ((nt)->sub[(nidx) >> nt_log2_sub_size].strings->strings +\
122    ((nidx) & nt_sub_index_mask))
123 		/* ref => string */
124 #define names_string_inline(nt, pnref)\
125   names_index_string_inline(nt, names_index_inline(nt, pnref))
126 		/* ref => index */
127 #if EXTEND_NAMES
128 #  define names_index_inline(nt_ignored, pnref)\
129      ( ((const name_sub_table *)\
130 	((pnref)->value.pname - (r_size(pnref) & nt_sub_index_mask)))->high_index + r_size(pnref) )
131 #else
132 #  define names_index_inline(nt_ignored, pnref) r_size(pnref)
133 #endif
134 #define names_index(nt_ignored, pnref) names_index_inline(nt_ignored, pnref)
135 		/* index => name */
136 #define names_index_ptr_inline(nt, nidx)\
137   ((nt)->sub[(nidx) >> nt_log2_sub_size].names->names +\
138    ((nidx) & nt_sub_index_mask))
139 		/* index => ref */
140 #define names_index_ref_inline(nt, nidx, pnref)\
141   make_name(pnref, nidx, names_index_ptr_inline(nt, nidx));
142 /* Backward compatibility */
143 #define name_index_inline(pnref) names_index_inline(ignored, pnref)
144 #define name_index_ptr_inline(nt, pnref) names_index_ptr_inline(nt, pnref)
145 #define name_index_ref_inline(nt, nidx, pnref)\
146   names_index_ref_inline(nt, nidx, pnref)
147 		/* name => ref */
148 /* We have to set the space to system so that the garbage collector */
149 /* won't think names are foreign and therefore untraceable. */
150 #define make_name(pnref, nidx, pnm)\
151   make_tasv(pnref, t_name, avm_system, (ushort)(nidx), pname, pnm)
152 
153 /* ------ Garbage collection ------ */
154 
155 /* Unmark all non-permanent names before a garbage collection. */
156 void names_unmark_all(name_table * nt);
157 
158 /* Finish tracing the name table by putting free names on the free list. */
159 void names_trace_finish(name_table * nt, gc_state_t * gcst);
160 
161 /* ------ Save/restore ------ */
162 
163 /* Clean up the name table before a restore. */
164 #ifndef alloc_save_t_DEFINED	/* also in isave.h */
165 typedef struct alloc_save_s alloc_save_t;
166 #  define alloc_save_t_DEFINED
167 #endif
168 void names_restore(name_table * nt, alloc_save_t * save);
169 
170 #endif /* inamedef_INCLUDED */
171