(state_compare): Now inline. Return bool, not int.

(state_comparator, stage_hasher): New function, to avoid casts.
(state_hash_new): Use new functions instead of casting old functions unportably.
(state_hash_lookup): Use MALLOC rather than alloca, so that we don't
have to worry about alloca.
(TRANSITIONS_ALLOC, ERRS_ALLOC, REDUCTIONS_ALLOC,
STATE_ALLOC): Remove.
(transitions_new, errs_new, reductions_new, state_new): Use malloc
rather than calloc, and use offsetof to avoid allocating slightly
too much storage.
(state_new): Initialize all members.
(state_hash): Use unsigned accumulator, not signed.
This commit is contained in:
Paul Eggert
2002-12-13 08:37:52 +00:00
parent 3b1e470c6d
commit 03b9e27342

View File

@@ -1,4 +1,5 @@
/* Type definitions for nondeterministic finite state machine for Bison. /* Type definitions for nondeterministic finite state machine for Bison.
Copyright (C) 2001, 2002 Free Software Foundation, Inc. Copyright (C) 2001, 2002 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler. This file is part of Bison, the GNU Compiler Compiler.
@@ -33,21 +34,17 @@
`-------------------*/ `-------------------*/
/*---------------------------------------. /*-----------------------------------------.
| Create a new array of N shifts/gotos. | | Create a new array of NUM shifts/gotos. |
`---------------------------------------*/ `-----------------------------------------*/
#define TRANSITIONS_ALLOC(Num) \
(transitions *) xcalloc ((sizeof (transitions) \
+ (Num - 1) * sizeof (state *)), \
1)
static transitions * static transitions *
transitions_new (int num, state **the_states) transitions_new (int num, state **the_states)
{ {
transitions *res = TRANSITIONS_ALLOC (num); size_t states_size = num * sizeof *the_states;
transitions *res = xmalloc (offsetof (transitions, states) + states_size);
res->num = num; res->num = num;
memcpy (res->states, the_states, num * sizeof (the_states[0])); memcpy (res->states, the_states, states_size);
return res; return res;
} }
@@ -73,20 +70,17 @@ transitions_to (transitions *shifts, symbol_number s)
`--------------------*/ `--------------------*/
/*-------------------------------. /*---------------------------------.
| Create a new array of N errs. | | Create a new array of NUM errs. |
`-------------------------------*/ `---------------------------------*/
#define ERRS_ALLOC(Nerrs) \
((errs *) xcalloc ((sizeof (errs) + (Nerrs - 1) * sizeof (symbol *)), 1))
errs * errs *
errs_new (int num, symbol **tokens) errs_new (int num, symbol **tokens)
{ {
errs *res = ERRS_ALLOC (num); size_t symbols_size = num * sizeof *tokens;
errs *res = xmalloc (offsetof (errs, symbols) + symbols_size);
res->num = num; res->num = num;
memcpy (res->symbols, tokens, num * sizeof (tokens[0])); memcpy (res->symbols, tokens, symbols_size);
return res; return res;
} }
@@ -98,21 +92,18 @@ errs_new (int num, symbol **tokens)
`-------------*/ `-------------*/
/*-------------------------------------. /*---------------------------------------.
| Create a new array of N reductions. | | Create a new array of NUM reductions. |
`-------------------------------------*/ `---------------------------------------*/
#define REDUCTIONS_ALLOC(Nreductions) \
(reductions *) xcalloc ((sizeof (reductions) \
+ (Nreductions - 1) * sizeof (rule *)), 1)
static reductions * static reductions *
reductions_new (int num, rule **reds) reductions_new (int num, rule **reds)
{ {
reductions *res = REDUCTIONS_ALLOC (num); size_t rules_size = num * sizeof *reds;
reductions *res = xmalloc (offsetof (reductions, rules) + rules_size);
res->num = num; res->num = num;
memcpy (res->rules, reds, num * sizeof (reds[0]));
res->lookaheads = NULL; res->lookaheads = NULL;
memcpy (res->rules, reds, rules_size);
return res; return res;
} }
@@ -128,10 +119,6 @@ state_number nstates = 0;
accessing symbol: $end. */ accessing symbol: $end. */
state *final_state = NULL; state *final_state = NULL;
#define STATE_ALLOC(Nitems) \
(state *) xcalloc ((sizeof (state) \
+ (Nitems - 1) * sizeof (item_number)), \
1)
/*------------------------------------------------------------------. /*------------------------------------------------------------------.
| Create a new state with ACCESSING_SYMBOL, for those items. Store | | Create a new state with ACCESSING_SYMBOL, for those items. Store |
@@ -140,21 +127,25 @@ state *final_state = NULL;
state * state *
state_new (symbol_number accessing_symbol, state_new (symbol_number accessing_symbol,
size_t core_size, item_number *core) size_t nitems, item_number *core)
{ {
state *res; state *res;
size_t items_size = nitems * sizeof *core;
if (STATE_NUMBER_MAXIMUM <= nstates) if (STATE_NUMBER_MAXIMUM <= nstates)
abort (); abort ();
res = STATE_ALLOC (core_size); res = xmalloc (offsetof (state, items) + items_size);
res->number = nstates++;
res->accessing_symbol = accessing_symbol; res->accessing_symbol = accessing_symbol;
res->number = nstates; res->transitions = NULL;
++nstates; res->reductions = NULL;
res->errs = NULL;
res->consistent = 0;
res->solved_conflicts = NULL; res->solved_conflicts = NULL;
res->nitems = core_size; res->nitems = nitems;
memcpy (res->items, core, core_size * sizeof (core[0])); memcpy (res->items, core, items_size);
state_hash_insert (res); state_hash_insert (res);
@@ -266,7 +257,7 @@ state_rule_lookaheads_print (state *s, rule *r, FILE *out)
static struct hash_table *state_table = NULL; static struct hash_table *state_table = NULL;
/* Two states are equal if they have the same core items. */ /* Two states are equal if they have the same core items. */
static bool static inline bool
state_compare (state const *s1, state const *s2) state_compare (state const *s1, state const *s2)
{ {
int i; int i;
@@ -281,17 +272,29 @@ state_compare (state const *s1, state const *s2)
return true; return true;
} }
static unsigned int static bool
state_comparator (void const *s1, void const *s2)
{
return state_compare (s1, s2);
}
static inline unsigned int
state_hash (state const *s, unsigned int tablesize) state_hash (state const *s, unsigned int tablesize)
{ {
/* Add up the state's item numbers to get a hash key. */ /* Add up the state's item numbers to get a hash key. */
int key = 0; unsigned int key = 0;
int i; int i;
for (i = 0; i < s->nitems; ++i) for (i = 0; i < s->nitems; ++i)
key += s->items[i]; key += s->items[i];
return key % tablesize; return key % tablesize;
} }
static unsigned int
state_hasher (void const *s, unsigned int tablesize)
{
return state_hash (s, tablesize);
}
/*-------------------------------. /*-------------------------------.
| Create the states hash table. | | Create the states hash table. |
@@ -302,9 +305,9 @@ state_hash_new (void)
{ {
state_table = hash_initialize (HT_INITIAL_CAPACITY, state_table = hash_initialize (HT_INITIAL_CAPACITY,
NULL, NULL,
(Hash_hasher) state_hash, state_hasher,
(Hash_comparator) state_compare, state_comparator,
(Hash_data_freer) NULL); NULL);
} }
@@ -336,13 +339,14 @@ state_hash_insert (state *s)
`------------------------------------------------------------------*/ `------------------------------------------------------------------*/
state * state *
state_hash_lookup (size_t core_size, item_number *core) state_hash_lookup (size_t nitems, item_number *core)
{ {
state *probe = STATE_ALLOC (core_size); size_t items_size = nitems * sizeof *core;
state *probe = xmalloc (offsetof (state, items) + items_size);
state *entry; state *entry;
probe->nitems = core_size; probe->nitems = nitems;
memcpy (probe->items, core, core_size * sizeof (core[0])); memcpy (probe->items, core, items_size);
entry = hash_lookup (state_table, probe); entry = hash_lookup (state_table, probe);
free (probe); free (probe);
return entry; return entry;