Some compiler cleanup and minor memory leak fixes.

This patch cleans up some unneeded code. Releases some allocated
memory before the compiler quits and fixes a couple minor memory
leaks in the compiler and vvp code generator.
This commit is contained in:
Cary R 2009-06-09 13:12:45 -07:00 committed by Stephen Williams
parent 5a30355faf
commit 75d71fe312
15 changed files with 126 additions and 42 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com) * Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -25,6 +25,11 @@
# include <string.h> # include <string.h>
# include <assert.h> # include <assert.h>
#ifdef CHECK_WITH_VALGRIND
static char **string_pool = NULL;
static unsigned string_pool_count = 0;
#endif
StringHeap::StringHeap() StringHeap::StringHeap()
{ {
cell_base_ = 0; cell_base_ = 0;
@ -46,6 +51,12 @@ const char* StringHeap::add(const char*text)
unsigned rem = HEAPCELL - cell_ptr_; unsigned rem = HEAPCELL - cell_ptr_;
if (rem < (len+1)) { if (rem < (len+1)) {
cell_base_ = (char*)malloc(HEAPCELL); cell_base_ = (char*)malloc(HEAPCELL);
#ifdef CHECK_WITH_VALGRIND
string_pool_count += 1;
string_pool = (char **) realloc(string_pool,
string_pool_count*sizeof(char **));
string_pool[string_pool_count-1] = cell_base_;
#endif
cell_ptr_ = 0; cell_ptr_ = 0;
cell_count_ += 1; cell_count_ += 1;
assert(cell_base_ != 0); assert(cell_base_ != 0);
@ -80,6 +91,22 @@ StringHeapLex::~StringHeapLex()
{ {
} }
void StringHeapLex::cleanup()
{
#ifdef CHECK_WITH_VALGRIND
for (unsigned idx = 0 ; idx < string_pool_count ; idx += 1) {
free(string_pool[idx]);
}
free(string_pool);
string_pool = NULL;
string_pool_count = 0;
for (unsigned idx = 0 ; idx < HASH_SIZE ; idx += 1) {
hash_table_[idx] = 0;
}
#endif
}
unsigned StringHeapLex::add_hit_count() const unsigned StringHeapLex::add_hit_count() const
{ {
return hit_count_; return hit_count_;
@ -175,4 +202,3 @@ bool operator < (perm_string a, perm_string b)
return false; return false;
} }

View File

@ -1,7 +1,7 @@
#ifndef __StringHeap_H #ifndef __StringHeap_H
#define __StringHeap_H #define __StringHeap_H
/* /*
* Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com) * Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -104,6 +104,7 @@ class StringHeapLex : private StringHeap {
unsigned add_count() const; unsigned add_count() const;
unsigned add_hit_count() const; unsigned add_hit_count() const;
void cleanup();
private: private:
enum { HASH_SIZE = 4096 }; enum { HASH_SIZE = 4096 };

View File

@ -202,5 +202,6 @@ struct sfunc_return_type {
extern const struct sfunc_return_type* lookup_sys_func(const char*name); extern const struct sfunc_return_type* lookup_sys_func(const char*name);
extern int load_sys_func_table(const char*path); extern int load_sys_func_table(const char*path);
extern void cleanup_sys_func_table();
#endif #endif

View File

@ -1,7 +1,7 @@
#ifndef __config_H /* -*- c++ -*- */ #ifndef __config_H /* -*- c++ -*- */
#define __config_H #define __config_H
/* /*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com) * Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -50,4 +50,10 @@
# include <inttypes.h> # include <inttypes.h>
#endif #endif
/*
* Define this if you want to compile vvp with memory freeing and
* special valgrind hooks for the memory pools.
*/
# undef CHECK_WITH_VALGRIND
#endif /* __config_H */ #endif /* __config_H */

View File

@ -3786,14 +3786,12 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
/* Do not elaborate specify delay paths if this feature is /* Do not elaborate specify delay paths if this feature is
turned off. */ turned off. */
if (!gn_specify_blocks_flag) if (!gn_specify_blocks_flag) return;
return;
ivl_assert(*this, conditional || (condition==0)); ivl_assert(*this, conditional || (condition==0));
ndelays = delays.size(); ndelays = delays.size();
if (ndelays > 12) if (ndelays > 12) ndelays = 12;
ndelays = 12;
/* Print a warning if we find default and `timescale based /* Print a warning if we find default and `timescale based
* delays in the design, since this is likely an error. */ * delays in the design, since this is likely an error. */
@ -4453,6 +4451,7 @@ Design* elaborate(list<perm_string>roots)
NetScope *scope = root_elems[i]->scope; NetScope *scope = root_elems[i]->scope;
rc &= rmod->elaborate(des, scope); rc &= rmod->elaborate(des, scope);
delete root_elems[i];
} }
if (rc == false) { if (rc == false) {

View File

@ -1374,3 +1374,17 @@ void reset_lexor()
/* Announce the first file name. */ /* Announce the first file name. */
yylloc.text = set_file_name(strdupnew(vl_file.c_str())); yylloc.text = set_file_name(strdupnew(vl_file.c_str()));
} }
/*
* Modern version of flex (>=2.5.9) can clean up the scanner data.
*/
void destroy_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
}

37
main.cc
View File

@ -77,7 +77,7 @@ extern "C" const char*optarg;
/* Count errors detected in flag processing. */ /* Count errors detected in flag processing. */
unsigned flag_errors = 0; unsigned flag_errors = 0;
const char*basedir = "."; const char*basedir = strdup(".");
/* /*
* These are the language support control flags. These support which * These are the language support control flags. These support which
@ -280,7 +280,7 @@ static void parm_to_flagmap(const string&flag)
unsigned off = flag.find('='); unsigned off = flag.find('=');
if (off > flag.size()) { if (off > flag.size()) {
key = flag; key = flag;
value = ""; value = strdup("");
} else { } else {
key = flag.substr(0, off); key = flag.substr(0, off);
@ -399,6 +399,7 @@ static void read_iconfig_file(const char*ipath)
} }
if (strcmp(buf, "basedir") == 0) { if (strcmp(buf, "basedir") == 0) {
free((char *)basedir);
basedir = strdup(cp); basedir = strdup(cp);
} else if (strcmp(buf, "debug") == 0) { } else if (strcmp(buf, "debug") == 0) {
@ -472,6 +473,7 @@ static void read_iconfig_file(const char*ipath)
flags["VPI_MODULE_LIST"] = vpi_module_list; flags["VPI_MODULE_LIST"] = vpi_module_list;
} else if (strcmp(buf, "out") == 0) { } else if (strcmp(buf, "out") == 0) {
free((char *)flags["-o"]);
flags["-o"] = strdup(cp); flags["-o"] = strdup(cp);
} else if (strcmp(buf, "sys_func") == 0) { } else if (strcmp(buf, "sys_func") == 0) {
@ -529,6 +531,7 @@ static void read_iconfig_file(const char*ipath)
} }
} }
fclose(ifile);
} }
extern Design* elaborate(list <perm_string> root); extern Design* elaborate(list <perm_string> root);
@ -555,6 +558,30 @@ inline static void times(struct tms *) { }
inline static double cycles_diff(struct tms *a, struct tms *b) { return 0; } inline static double cycles_diff(struct tms *a, struct tms *b) { return 0; }
#endif // ! defined(HAVE_TIMES) #endif // ! defined(HAVE_TIMES)
static void EOC_cleanup(void)
{
cleanup_sys_func_table();
for (list<const char*>::iterator suf = library_suff.begin() ;
suf != library_suff.end() ; suf ++ ) {
free((char *)*suf);
}
library_suff.clear();
free((char *) basedir);
free(ivlpp_string);
free(depfile_name);
for (map<string, const char*>::iterator flg = flags.begin() ;
flg != flags.end() ; flg ++ ) {
free((char *)flg->second);
}
flags.clear();
lex_strings.cleanup();
filename_strings.cleanup();
}
int main(int argc, char*argv[]) int main(int argc, char*argv[])
{ {
bool help_flag = false; bool help_flag = false;
@ -567,11 +594,11 @@ int main(int argc, char*argv[])
struct tms cycles[5]; struct tms cycles[5];
library_suff.push_back(".v"); library_suff.push_back(strdup(".v"));
vpi_module_list = strdup("system"); vpi_module_list = strdup("system");
flags["VPI_MODULE_LIST"] = vpi_module_list; flags["VPI_MODULE_LIST"] = vpi_module_list;
flags["-o"] = "a.out"; flags["-o"] = strdup("a.out");
min_typ_max_flag = TYP; min_typ_max_flag = TYP;
min_typ_max_warn = 10; min_typ_max_warn = 10;
@ -933,6 +960,8 @@ int main(int argc, char*argv[])
<< endl; << endl;
} }
delete des;
EOC_cleanup();
return 0; return 0;
errors_summary: errors_summary:

View File

@ -60,6 +60,8 @@ extern void VLerror(const YYLTYPE&loc, const char*msg);
#define yywarn VLwarn #define yywarn VLwarn
extern void VLwarn(const YYLTYPE&loc, const char*msg); extern void VLwarn(const YYLTYPE&loc, const char*msg);
extern void destroy_lexor();
extern ostream& operator << (ostream&, const YYLTYPE&loc); extern ostream& operator << (ostream&, const YYLTYPE&loc);
extern unsigned error_count, warn_count; extern unsigned error_count, warn_count;

View File

@ -2170,6 +2170,7 @@ int pform_parse(const char*path, FILE*file)
error_count += 1; error_count += 1;
} }
destroy_lexor();
return error_count; return error_count;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2004-2008 Stephen Williams (steve@icarus.com) * Copyright (c) 2004-2009 Stephen Williams (steve@icarus.com)
* *
* This source code is free software; you can redistribute it * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -46,6 +46,16 @@ struct sfunc_return_type_cell : sfunc_return_type {
static struct sfunc_return_type_cell*sfunc_stack = 0; static struct sfunc_return_type_cell*sfunc_stack = 0;
void cleanup_sys_func_table()
{
struct sfunc_return_type_cell *next, *cur = sfunc_stack;
while (cur) {
next = cur->next;
delete cur;
cur = next;
}
}
const struct sfunc_return_type* lookup_sys_func(const char*name) const struct sfunc_return_type* lookup_sys_func(const char*name)
{ {
/* First, try to find then name in the function stack. */ /* First, try to find then name in the function stack. */
@ -186,7 +196,7 @@ int load_sys_func_table(const char*path)
fprintf(stderr, "%s:%s: Unknown type: %s\n", fprintf(stderr, "%s:%s: Unknown type: %s\n",
path, name, stype); path, name, stype);
} }
fclose(fd);
return 0; return 0;
} }

View File

@ -19,9 +19,6 @@
# include "vvp_priv.h" # include "vvp_priv.h"
# include <assert.h> # include <assert.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.h> # include <stdlib.h>
# include <string.h> # include <string.h>

View File

@ -505,6 +505,16 @@ static char* draw_island_port(ivl_island_t island,
/* Omit LPMPART_BI device pin-data(0) drivers. */ /* Omit LPMPART_BI device pin-data(0) drivers. */
# define OMIT_PART_BI_DATA 0x0001 # define OMIT_PART_BI_DATA 0x0001
static ivl_nexus_ptr_t *drivers = 0x0;
static unsigned adrivers = 0;
void EOC_cleanup_drivers()
{
free(drivers);
drivers = NULL;
adrivers = 0;
}
char* draw_net_input_x(ivl_nexus_t nex, char* draw_net_input_x(ivl_nexus_t nex,
ivl_nexus_ptr_t omit_ptr, int omit_flags, ivl_nexus_ptr_t omit_ptr, int omit_flags,
struct vvp_nexus_data*nex_data) struct vvp_nexus_data*nex_data)
@ -515,8 +525,6 @@ char* draw_net_input_x(ivl_nexus_t nex,
unsigned idx; unsigned idx;
int level; int level;
unsigned ndrivers = 0; unsigned ndrivers = 0;
static ivl_nexus_ptr_t *drivers = 0x0;
static unsigned adrivers = 0;
const char*resolv_type; const char*resolv_type;

View File

@ -140,6 +140,7 @@ int target_design(ivl_design_t des)
} }
fclose(vvp_out); fclose(vvp_out);
EOC_cleanup_drivers();
return rc + vvp_errors; return rc + vvp_errors;
} }

View File

@ -1,7 +1,7 @@
#ifndef __vvp_priv_H #ifndef __vvp_priv_H
#define __vvp_priv_H #define __vvp_priv_H
/* /*
* 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * and/or modify it in source code form under the terms of the GNU
@ -141,6 +141,7 @@ struct vvp_nexus_data {
* cache it. * cache it.
*/ */
extern const char* draw_net_input(ivl_nexus_t nex); extern const char* draw_net_input(ivl_nexus_t nex);
void EOC_cleanup_drivers();
/* /*
* See draw_net_input.c for details on draw_net_input_x. (It would be * See draw_net_input.c for details on draw_net_input_x. (It would be

View File

@ -665,25 +665,12 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
ivl_drive_t str0, str1; ivl_drive_t str0, str1;
int level; int level;
int ninp = ivl_logic_pins(lptr) - 1; int ninp;
typedef const char*const_charp; const char **input_strings;
const_charp*input_strings = calloc(ninp, sizeof(const_charp));
for (pdx = 0 ; pdx < ninp ; pdx += 1) {
ivl_nexus_t nex = ivl_logic_pin(lptr, pdx+1);
if (nex == 0) {
/* Only UDPs can have unconnected inputs. */
assert(ivl_logic_type(lptr) == IVL_LO_UDP);
input_strings[pdx] = 0;
} else {
input_strings[pdx] = draw_net_input(nex);
}
}
switch (ivl_logic_type(lptr)) { switch (ivl_logic_type(lptr)) {
case IVL_LO_UDP: case IVL_LO_UDP:
free(input_strings);
draw_udp_in_scope(lptr); draw_udp_in_scope(lptr);
return; return;
@ -706,7 +693,6 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
/* Skip pullup and pulldown objects. Things that have /* Skip pullup and pulldown objects. Things that have
pull objects as inputs will instead generate the pull objects as inputs will instead generate the
appropriate C<?> symbol. */ appropriate C<?> symbol. */
free(input_strings);
return; return;
case IVL_LO_AND: case IVL_LO_AND:
@ -1862,12 +1848,14 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
fprintf(vvp_out, ">;\n"); fprintf(vvp_out, ">;\n");
break; break;
case IVL_EX_REALNUM: case IVL_EX_REALNUM:
fprintf(vvp_out, "P_%p .param/real \"%s\" %d %d, %s; value=%#g\n", { char *res = draw_Cr_to_string(ivl_expr_dvalue(pex));
par, ivl_parameter_basename(par), fprintf(vvp_out, "P_%p .param/real \"%s\" %d %d, %s; "
ivl_file_table_index(ivl_parameter_file(par)), "value=%#g\n", par, ivl_parameter_basename(par),
ivl_parameter_lineno(par), ivl_file_table_index(ivl_parameter_file(par)),
draw_Cr_to_string(ivl_expr_dvalue(pex)), ivl_parameter_lineno(par), res,
ivl_expr_dvalue(pex)); ivl_expr_dvalue(pex));
free(res);
}
break; break;
default: default:
fprintf(vvp_out, "; parameter type %d unsupported\n", fprintf(vvp_out, "; parameter type %d unsupported\n",