From a05d8c28230183b1112ae0e583b1e97a66215c81 Mon Sep 17 00:00:00 2001 From: steve Date: Fri, 5 Jul 2002 04:40:59 +0000 Subject: [PATCH] Symbol table uses more efficient key string allocator, and remove all the symbol tables after compile is done. --- vvp/compile.cc | 31 ++++++++++++---------- vvp/debug.cc | 19 +++++-------- vvp/symbols.cc | 72 +++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 80 insertions(+), 42 deletions(-) diff --git a/vvp/compile.cc b/vvp/compile.cc index faa5f10e7..da9bfefe9 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: compile.cc,v 1.132 2002/07/05 02:50:58 steve Exp $" +#ident "$Id: compile.cc,v 1.133 2002/07/05 04:40:59 steve Exp $" #endif # include "arith.h" @@ -195,6 +195,7 @@ void define_functor_symbol(const char*label, vvp_ipoint_t ipt) static vvp_ipoint_t lookup_functor_symbol(const char*label) { + assert(sym_functors); symbol_value_t val = sym_get_value(sym_functors, label); return val.num; } @@ -491,8 +492,19 @@ void compile_cleanup(void) compile_errors += nerrs; + /* After compile is complete, the vpi symbol table is no + longer needed. VPI objects are located by following + scopes. */ delete_symbol_table(sym_vpi); sym_vpi = 0; + + /* Don't need the code labels. The instructions have numeric + pointers in them, the symbol table is no longer needed. */ + delete_symbol_table(sym_codespace); + sym_codespace = 0; + + delete_symbol_table(sym_functors); + sym_functors = 0; } void compile_vpi_symbol(const char*label, vpiHandle obj) @@ -1405,21 +1417,12 @@ void compile_net(char*label, char*name, int msb, int lsb, bool signed_flag, free(argv); } -/* - * These functions are in support of the debugger. - * - * debug_lookup_functor - * Use a name to locate a functor address. This only gets the LSB - * of a vector, but it is enough to locate the object, or, is it? - */ -vvp_ipoint_t debug_lookup_functor(const char*name) -{ - return lookup_functor_symbol(name); -} - - /* * $Log: compile.cc,v $ + * Revision 1.133 2002/07/05 04:40:59 steve + * Symbol table uses more efficient key string allocator, + * and remove all the symbol tables after compile is done. + * * Revision 1.132 2002/07/05 02:50:58 steve * Remove the vpi object symbol table after compile. * diff --git a/vvp/debug.cc b/vvp/debug.cc index d8995cb65..583a3073d 100644 --- a/vvp/debug.cc +++ b/vvp/debug.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: debug.cc,v 1.8 2001/12/18 05:32:11 steve Exp $" +#ident "$Id: debug.cc,v 1.9 2002/07/05 04:40:59 steve Exp $" #endif /* @@ -45,20 +45,9 @@ static bool interact_flag = false; -extern vvp_ipoint_t debug_lookup_functor(const char*name); - static void cmd_lookup(unsigned argc, char*argv[]) { - for (unsigned idx = 1 ; idx < argc ; idx += 1) { - vvp_ipoint_t fnc = debug_lookup_functor(argv[idx]); - - if (fnc) { - printf("%s: functor 0x%x\n", argv[idx], fnc); - continue; - } - - printf("%s: *** unknown\n", argv[idx]); - } + printf(" **** not implemented...\n"); } static void cmd_fbreak(unsigned argc, char*argv[]) @@ -165,6 +154,10 @@ void breakpoint(void) #endif /* * $Log: debug.cc,v $ + * Revision 1.9 2002/07/05 04:40:59 steve + * Symbol table uses more efficient key string allocator, + * and remove all the symbol tables after compile is done. + * * Revision 1.8 2001/12/18 05:32:11 steve * Improved functor debug dumps. * diff --git a/vvp/symbols.cc b/vvp/symbols.cc index dff576552..77559f5f4 100644 --- a/vvp/symbols.cc +++ b/vvp/symbols.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: symbols.cc,v 1.6 2002/07/05 02:50:58 steve Exp $" +#ident "$Id: symbols.cc,v 1.7 2002/07/05 04:40:59 steve Exp $" #endif # include "symbols.h" @@ -28,10 +28,44 @@ #endif # include +/* + * The keys of the symbol table are null terminated strings. Keep them + * in a string buffer, with the strings separated by a single null, + * for compact use of memory. This also makes it easy to delete the + * entire lot of keys, simply by deleting the heaps. + * + * The key_strdup() function below allocates the strings from this + * buffer, possibly making a new buffer if needed. + */ +struct key_strings { + struct key_strings*next; + char data[64*1024 - sizeof(struct key_strings*)]; +}; + struct symbol_table_s { struct tree_node_*root; + struct key_strings*str_chunk; + unsigned str_used; }; +static char*key_strdup(struct symbol_table_s*tab, const char*str) +{ + unsigned len = strlen(str); + assert( (len+1) <= sizeof tab->str_chunk->data ); + + if ( (len+1) > (sizeof tab->str_chunk->data - tab->str_used) ) { + key_strings*tmp = new key_strings; + tmp->next = tab->str_chunk; + tab->str_chunk = tmp; + tab->str_used = 0; + } + + char*res = tab->str_chunk->data + tab->str_used; + tab->str_used += len + 1; + strcpy(res, str); + return res; +} + /* * This is a B-Tree data structure, where there are nodes and * leaves. @@ -84,28 +118,32 @@ symbol_table_t new_symbol_table(void) tbl->root->leaf_flag = false; tbl->root->count = 0; tbl->root->parent = 0; + + tbl->str_chunk = new key_strings; + tbl->str_used = 0; + return tbl; } static void delete_symbol_node(struct tree_node_*cur) { - if (cur->leaf_flag) { + if (! cur->leaf_flag) { for (unsigned idx = 0 ; idx < cur->count ; idx += 1) - free(cur->leaf[idx].key); - - delete cur; - - } else { - for (unsigned idx = 0 ; idx < cur->count ; idx += 1) - delete cur->child[idx]; - - delete cur; + delete_symbol_node(cur->child[idx]); } + + delete cur; } void delete_symbol_table(symbol_table_t tab) { delete_symbol_node(tab->root); + while (tab->str_chunk) { + key_strings*tmp = tab->str_chunk; + tab->str_chunk = tmp->next; + delete tmp; + } + delete tab; } @@ -261,7 +299,7 @@ static symbol_value_t find_value_(symbol_table_t tbl, struct tree_node_*cur, /* If we run out of keys in the leaf, then add this at the end of the leaf. */ if (idx == cur->count) { - cur->leaf[idx].key = strdup(key); + cur->leaf[idx].key = key_strdup(tbl, key); cur->leaf[idx].val = val; cur->count += 1; if (cur->count == leaf_width) @@ -287,7 +325,7 @@ static symbol_value_t find_value_(symbol_table_t tbl, struct tree_node_*cur, for (unsigned tmp = cur->count; tmp > idx; tmp -= 1) cur->leaf[tmp] = cur->leaf[tmp-1]; - cur->leaf[idx].key = strdup(key); + cur->leaf[idx].key = key_strdup(tbl, key); cur->leaf[idx].val = val; cur->count += 1; if (cur->count == leaf_width) @@ -349,7 +387,7 @@ void sym_set_value(symbol_table_t tbl, const char*key, symbol_value_t val) cur->leaf_flag = true; cur->parent = tbl->root; cur->count = 1; - cur->leaf[0].key = strdup(key); + cur->leaf[0].key = key_strdup(tbl, key); cur->leaf[0].val = val; tbl->root->count = 1; @@ -372,7 +410,7 @@ symbol_value_t sym_get_value(symbol_table_t tbl, const char*key) cur->leaf_flag = true; cur->parent = tbl->root; cur->count = 1; - cur->leaf[0].key = strdup(key); + cur->leaf[0].key = key_strdup(tbl, key); cur->leaf[0].val = def; tbl->root->count = 1; @@ -386,6 +424,10 @@ symbol_value_t sym_get_value(symbol_table_t tbl, const char*key) /* * $Log: symbols.cc,v $ + * Revision 1.7 2002/07/05 04:40:59 steve + * Symbol table uses more efficient key string allocator, + * and remove all the symbol tables after compile is done. + * * Revision 1.6 2002/07/05 02:50:58 steve * Remove the vpi object symbol table after compile. *