diff --git a/vpi/sdf_lexor.lex b/vpi/sdf_lexor.lex index accb02ed1..5f39380a9 100644 --- a/vpi/sdf_lexor.lex +++ b/vpi/sdf_lexor.lex @@ -5,7 +5,7 @@ %{ /* - * Copyright (c) 2007 Stephen Williams (steve@icarus.com) + * Copyright (c) 2007-2009 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -151,6 +151,20 @@ static void process_quoted_string(void) endp[-1] = 0; } +/* + * Modern version of flex (>=2.5.9) can clean up the scanner data. + */ +static void destroy_sdf_lexor() +{ +# ifdef FLEX_SCANNER +# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5 +# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9 + yylex_destroy(); +# endif +# endif +# endif +} + extern int sdfparse(void); void sdf_process_file(FILE*fd, const char*path) { @@ -158,5 +172,6 @@ void sdf_process_file(FILE*fd, const char*path) sdf_parse_path = path; sdfparse(); + destroy_sdf_lexor(); sdf_parse_path = 0; } diff --git a/vpi/stringheap.c b/vpi/stringheap.c index 051b9aa9e..9369401de 100644 --- a/vpi/stringheap.c +++ b/vpi/stringheap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Stephen Williams (steve@icarus.com) + * Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -60,3 +60,14 @@ const char*strdup_sh(struct stringheap_s*hp, const char*txt) return res; } +void string_heap_delete(struct stringheap_s*hp) +{ + struct stringheap_cell *cur, *tmp; + + for (cur = hp->cell_lst; cur ; cur = tmp) { + tmp = cur->next; + free((char *)cur); + } + hp->cell_lst = 0; + hp->cell_off = 0; +} diff --git a/vpi/stringheap.h b/vpi/stringheap.h index f0c6546a4..2c383d124 100644 --- a/vpi/stringheap.h +++ b/vpi/stringheap.h @@ -1,7 +1,7 @@ #ifndef __stringheap_H #define __stringheap_H /* - * Copyright (c) 2003 Stephen Williams (steve@icarus.com) + * Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -31,4 +31,6 @@ struct stringheap_s { */ const char*strdup_sh(struct stringheap_s*hp, const char*str); +void string_heap_delete(struct stringheap_s*hp); + #endif diff --git a/vpi/sys_display.c b/vpi/sys_display.c index a9d10a800..0527a74c0 100644 --- a/vpi/sys_display.c +++ b/vpi/sys_display.c @@ -1615,12 +1615,6 @@ static PLI_INT32 sys_end_of_compile(p_cb_data cb_data) return 0; } -static PLI_INT32 sys_end_of_simulation(p_cb_data cb_data) -{ - free(timeformat_info.suff); - return 0; -} - static PLI_INT32 sys_timeformat_compiletf(PLI_BYTE8*name) { vpiHandle callh = vpi_handle(vpiSysTfCall, 0); @@ -1861,6 +1855,21 @@ static PLI_INT32 sys_printtimescale_calltf(PLI_BYTE8*xx) return 0; } +static PLI_INT32 sys_end_of_simulation(p_cb_data cb_data) +{ + free(monitor_callbacks); + monitor_callbacks = 0; + free(monitor_info.filename); + free(monitor_info.items); + monitor_info.items = 0; + monitor_info.nitems = 0; + monitor_info.name = 0; + + free(timeformat_info.suff); + timeformat_info.suff = 0; + return 0; +} + void sys_display_register() { s_cb_data cb_data; diff --git a/vpi/sys_readmem.c b/vpi/sys_readmem.c index 91f2a51b0..b6c09c07a 100644 --- a/vpi/sys_readmem.c +++ b/vpi/sys_readmem.c @@ -341,6 +341,7 @@ static PLI_INT32 sys_readmem_calltf(PLI_BYTE8*name) free(value.value.vector); free(path); fclose(file); + destroy_readmem_lexor(file); return 0; } diff --git a/vpi/sys_readmem_lex.h b/vpi/sys_readmem_lex.h index d8258b98a..e050e4c82 100644 --- a/vpi/sys_readmem_lex.h +++ b/vpi/sys_readmem_lex.h @@ -1,7 +1,7 @@ #ifndef __sys_readmem_lex_H #define __sys_readmem_lex_H /* - * Copyright (c) 1999 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -29,4 +29,6 @@ extern void sys_readmem_start_file(FILE*in, int bin_flag, unsigned width, struct t_vpi_vecval*val); extern int readmemlex(); +extern void destroy_readmem_lexor(); + #endif diff --git a/vpi/sys_readmem_lex.lex b/vpi/sys_readmem_lex.lex index 5205507c8..2cceeaba0 100644 --- a/vpi/sys_readmem_lex.lex +++ b/vpi/sys_readmem_lex.lex @@ -4,7 +4,7 @@ %{ /* - * Copyright (c) 1999 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -186,3 +186,17 @@ void sys_readmem_start_file(FILE*in, int bin_flag, word_width = width; vecval = vv; } + +/* + * Modern version of flex (>=2.5.9) can clean up the scanner data. + */ +void destroy_readmem_lexor() +{ +# ifdef FLEX_SCANNER +# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5 +# if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9 + yylex_destroy(); +# endif +# endif +# endif +} diff --git a/vpi/sys_vcd.c b/vpi/sys_vcd.c index 4685a2137..738832fd0 100644 --- a/vpi/sys_vcd.c +++ b/vpi/sys_vcd.c @@ -245,6 +245,7 @@ static PLI_INT32 dumpvars_cb(p_cb_data cause) static PLI_INT32 finish_cb(p_cb_data cause) { + if (finish_status != 0) return 0; finish_status = 1; @@ -255,6 +256,12 @@ static PLI_INT32 finish_cb(p_cb_data cause) fprintf(dump_file, "#%" PLI_UINT64_FMT "\n", dumpvars_time); } + vcd_names_delete(&vcd_tab); + vcd_names_delete(&vcd_var); + nexus_ident_delete(); + free(dump_path); + dump_path = 0; + return 0; } diff --git a/vpi/vcd_priv.c b/vpi/vcd_priv.c index 9f59d741e..79fd556ff 100644 --- a/vpi/vcd_priv.c +++ b/vpi/vcd_priv.c @@ -68,6 +68,21 @@ void vcd_names_add(struct vcd_names_list_s*tab, const char *name) tab->listed_names ++; } +void vcd_names_delete(struct vcd_names_list_s*tab) +{ + struct vcd_names_s *cur, *tmp; + for (cur = tab->vcd_names_list; cur; cur = tmp) { + tmp = cur->next; + free(cur); + } + tab->vcd_names_list = 0; + tab->listed_names = 0; + free(tab->vcd_names_sorted); + tab->vcd_names_sorted = 0; + tab->sorted_names = 0; + string_heap_delete(&name_heap); +} + static int vcd_names_compare(const void *s1, const void *s2) { const char *v1 = *(const char **) s1; @@ -186,6 +201,23 @@ void set_nexus_ident(int nex, const char *id) vcd_ids[ihash(nex)] = bucket; } +void nexus_ident_delete() +{ + unsigned idx; + + if (vcd_ids == 0) return; + + for (idx = 0 ; idx < 256; idx = idx += 1) { + struct vcd_id_s *cur, *tmp; + for (cur = vcd_ids[idx]; cur; cur = tmp) { + tmp = cur->next; + free(cur); + } + } + free(vcd_ids); + vcd_ids = 0; +} + /* * Since the compiletf routines are all the same they are located here, * so we only need a single copy. Some are generic enough they can use diff --git a/vpi/vcd_priv.h b/vpi/vcd_priv.h index 7daa498c3..19a29709b 100644 --- a/vpi/vcd_priv.h +++ b/vpi/vcd_priv.h @@ -1,7 +1,7 @@ #ifndef __vcd_priv_H #define __vcd_priv_H /* - * Copyright (c) 2003-2008 Stephen Williams (steve@icarus.com) + * Copyright (c) 2003-2009 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -39,10 +39,13 @@ extern const char *vcd_names_search(struct vcd_names_list_s*tab, extern void vcd_names_sort(struct vcd_names_list_s*tab); +extern void vcd_names_delete(); extern const char*find_nexus_ident(int nex); extern void set_nexus_ident(int nex, const char *id); +extern void nexus_ident_delete(); + /* The compiletf routines are common for the VCD, LXT and LXT2 dumpers. */ extern PLI_INT32 sys_dumpvars_compiletf(PLI_BYTE8 *name); diff --git a/vvp/main.cc b/vvp/main.cc index e9dac4ba1..979c34048 100644 --- a/vvp/main.cc +++ b/vvp/main.cc @@ -24,6 +24,7 @@ # include "schedule.h" # include "vpi_priv.h" # include "statistics.h" +# include "vvp_cleanup.h" # include # include # include @@ -424,6 +425,14 @@ int main(int argc, char*argv[]) cur != file_names.end() ; cur++) { delete[] *cur; } + (void)need_result_buf(0, RBUF_DEL); +// These are not finished. +// codespace_delete(); +// root_table_delete(); + def_table_delete(); + vpi_mcd_delete(); + dec_str_delete(); + load_module_delete(); return vvp_return_value; } diff --git a/vvp/vpi_mcd.cc b/vvp/vpi_mcd.cc index 9d2ff2aa8..0994637b7 100644 --- a/vvp/vpi_mcd.cc +++ b/vvp/vpi_mcd.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 Stephen G. Tell + * Copyright (c) 2000-2009 Stephen G. Tell * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -18,6 +18,7 @@ */ # include "vpi_priv.h" +# include "vvp_cleanup.h" # include # include # include @@ -67,6 +68,25 @@ void vpi_mcd_init(FILE *log) logfile = log; } +void vpi_mcd_delete(void) +{ + free(mcd_table[0].filename); + mcd_table[0].filename = 0; + mcd_table[0].fp = 0; + + free(fd_table[0].filename); + fd_table[0].filename = 0; + fd_table[0].fp = 0; + + free(fd_table[1].filename); + fd_table[1].filename = 0; + fd_table[1].fp = 0; + + free(fd_table[2].filename); + fd_table[2].filename = 0; + fd_table[2].fp = 0; +} + /* * close one or more channels. we silently refuse to close the preopened ones. */ diff --git a/vvp/vpi_modules.cc b/vvp/vpi_modules.cc index 1e63059cc..7e509a19b 100644 --- a/vvp/vpi_modules.cc +++ b/vvp/vpi_modules.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2008 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -20,11 +20,15 @@ # include "config.h" # include "vpi_priv.h" # include "ivl_dlfcn.h" +# include "vvp_cleanup.h" # include # include # include # include +static ivl_dll_t*dll_list = 0; +static unsigned dll_list_cnt = 0; + typedef void (*vlog_startup_routines_t)(void); @@ -47,6 +51,16 @@ unsigned vpip_module_path_cnt = 0 #endif ; +void load_module_delete(void) +{ + for (unsigned idx = 0; idx < dll_list_cnt; idx += 1) { + ivl_dlclose(dll_list[idx]); + } + free(dll_list); + dll_list = 0; + dll_list_cnt = 0; +} + void vpip_load_module(const char*name) { struct stat sb; @@ -142,6 +156,11 @@ void vpip_load_module(const char*name) return; } + /* Add the dll to the list so it can be closed when we are done. */ + dll_list_cnt += 1; + dll_list = (ivl_dll_t*)realloc(dll_list, dll_list_cnt*sizeof(ivl_dll_t)); + dll_list[dll_list_cnt-1] = dll; + vpi_mode_flag = VPI_MODE_REGISTER; vlog_startup_routines_t*routines = (vlog_startup_routines_t*)table; for (unsigned tmp = 0 ; routines[tmp] ; tmp += 1) diff --git a/vvp/vpi_priv.h b/vvp/vpi_priv.h index dc8b8fca6..78f7de203 100644 --- a/vvp/vpi_priv.h +++ b/vvp/vpi_priv.h @@ -587,8 +587,10 @@ extern void vpip_vec4_get_value(const vvp_vector4_t&word_val, unsigned width, enum vpi_rbuf_t { RBUF_VAL =0, /* Storage for *_get_value() */ - RBUF_STR + RBUF_STR, /* Storage for *_get_str() */ + RBUF_DEL + /* Delete the storage for both buffers. */ }; extern char *need_result_buf(unsigned cnt, vpi_rbuf_t type); /* following two routines use need_result_buf(, RBUF_STR) */ diff --git a/vvp/vpi_signal.cc b/vvp/vpi_signal.cc index 6941fc9bc..b70974f1b 100644 --- a/vvp/vpi_signal.cc +++ b/vvp/vpi_signal.cc @@ -57,11 +57,23 @@ extern const char oct_digits[64]; */ char *need_result_buf(unsigned cnt, vpi_rbuf_t type) { - cnt = (cnt + 0x0fff) & ~0x0fff; - static char*result_buf[2] = {0, 0}; static size_t result_buf_size[2] = {0, 0}; + if (type == RBUF_DEL) { + free(result_buf[RBUF_VAL]); + result_buf[RBUF_VAL] = 0; + result_buf_size[RBUF_VAL] = 0; + + free(result_buf[RBUF_STR]); + result_buf[RBUF_STR] = 0; + result_buf_size[RBUF_STR] = 0; + + return 0; + } + + cnt = (cnt + 0x0fff) & ~0x0fff; + if (result_buf_size[type] == 0) { result_buf[type] = (char*)malloc(cnt); result_buf_size[type] = cnt; diff --git a/vvp/vpi_tasks.cc b/vvp/vpi_tasks.cc index 114810b22..ba9d94fd5 100644 --- a/vvp/vpi_tasks.cc +++ b/vvp/vpi_tasks.cc @@ -25,6 +25,7 @@ # include "vpi_priv.h" # include "vthread.h" # include "compile.h" +# include "vvp_cleanup.h" # include #ifdef HAVE_MALLOC_H # include @@ -519,6 +520,16 @@ static struct __vpiUserSystf* allocate_def(void) return def_table[def_count++]; } +void def_table_delete(void) +{ + for (unsigned idx = 0; idx < def_count; idx += 1) { + free(const_cast(def_table[idx]->info.tfname)); + free(def_table[idx]); + } + free(def_table); + def_table = 0; + def_count = 0; +} struct __vpiUserSystf* vpip_find_systf(const char*name) { diff --git a/vvp/vpip_to_dec.cc b/vvp/vpip_to_dec.cc index ae189fbb1..7816db438 100644 --- a/vvp/vpip_to_dec.cc +++ b/vvp/vpip_to_dec.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Stephen Williams + * Copyright (c) 2008-2009 Stephen Williams * Copyright (c) 2002 Larry Doolittle (larry@doolittle.boa.org) * * This source code is free software; you can redistribute it @@ -20,6 +20,7 @@ # include "config.h" # include "vpi_priv.h" +# include "vvp_cleanup.h" # include # include # include /* for CHAR_BIT */ @@ -102,6 +103,17 @@ static inline int write_digits(unsigned long v, char **buf, return zero_suppress; } +/* Jump through some hoops so we don't have to malloc/free valv + * on every call, and implement an optional malloc-less version. */ +static unsigned long *valv=NULL; +static unsigned int vlen_alloc=0; + +void dec_str_delete(void) +{ + free(valv); + valv = 0; + vlen_alloc = 0; +} unsigned vpip_vec4_to_dec_str(const vvp_vector4_t&vec4, char *buf, unsigned int nbuf, @@ -110,10 +122,6 @@ unsigned vpip_vec4_to_dec_str(const vvp_vector4_t&vec4, unsigned int idx, len, vlen; unsigned int mbits=vec4.size(); /* number of non-sign bits */ unsigned count_x = 0, count_z = 0; - /* Jump through some hoops so we don't have to malloc/free valv - * on every call, and implement an optional malloc-less version. */ - static unsigned long *valv=NULL; - static unsigned int vlen_alloc=0; unsigned long val=0; int comp=0; @@ -215,8 +223,6 @@ unsigned vpip_vec4_to_dec_str(const vvp_vector4_t&vec4, /* printf("\n"); */ *buf='\0'; } - /* hold on to the memory, since we expect to be called again. */ - /* free(valv); */ return 0; } diff --git a/vvp/vvp_cleanup.h b/vvp/vvp_cleanup.h new file mode 100644 index 000000000..228ed8613 --- /dev/null +++ b/vvp/vvp_cleanup.h @@ -0,0 +1,33 @@ +#ifndef __vvp_cleanup_H +#define __vvp_cleanup_H +/* + * Copyright (c) 2009 Cary R. (cygcary@yahoo.com) + * + * This source code is free software; you can redistribute it + * and/or modify it in source code form under the terms of the GNU + * General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +# include "pointers.h" +# include "vpi_priv.h" +# include "vvp_net.h" + +/* Routines used to cleanup the runtime memory when it is all finished. */ + +extern void def_table_delete(void); +extern void vpi_mcd_delete(void); +extern void dec_str_delete(void); +extern void load_module_delete(void); + +#endif