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 f379cd0a14
commit d98c925f53
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
* and/or modify it in source code form under the terms of the GNU
@ -25,6 +25,11 @@
# include <string.h>
# include <assert.h>
#ifdef CHECK_WITH_VALGRIND
static char **string_pool = NULL;
static unsigned string_pool_count = 0;
#endif
StringHeap::StringHeap()
{
cell_base_ = 0;
@ -46,6 +51,12 @@ const char* StringHeap::add(const char*text)
unsigned rem = HEAPCELL - cell_ptr_;
if (rem < (len+1)) {
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_count_ += 1;
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
{
return hit_count_;
@ -175,4 +202,3 @@ bool operator < (perm_string a, perm_string b)
return false;
}

View File

@ -1,7 +1,7 @@
#ifndef __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
* 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_hit_count() const;
void cleanup();
private:
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 int load_sys_func_table(const char*path);
extern void cleanup_sys_func_table();
#endif

View File

@ -1,7 +1,7 @@
#ifndef __config_H /* -*- c++ -*- */
#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
* and/or modify it in source code form under the terms of the GNU
@ -50,4 +50,10 @@
# include <inttypes.h>
#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 */

View File

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

View File

@ -1374,3 +1374,17 @@ void reset_lexor()
/* Announce the first file name. */
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. */
unsigned flag_errors = 0;
const char*basedir = ".";
const char*basedir = strdup(".");
/*
* 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('=');
if (off > flag.size()) {
key = flag;
value = "";
value = strdup("");
} else {
key = flag.substr(0, off);
@ -399,6 +399,7 @@ static void read_iconfig_file(const char*ipath)
}
if (strcmp(buf, "basedir") == 0) {
free((char *)basedir);
basedir = strdup(cp);
} 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;
} else if (strcmp(buf, "out") == 0) {
free((char *)flags["-o"]);
flags["-o"] = strdup(cp);
} 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);
@ -555,6 +558,30 @@ inline static void times(struct tms *) { }
inline static double cycles_diff(struct tms *a, struct tms *b) { return 0; }
#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[])
{
bool help_flag = false;
@ -567,11 +594,11 @@ int main(int argc, char*argv[])
struct tms cycles[5];
library_suff.push_back(".v");
library_suff.push_back(strdup(".v"));
vpi_module_list = strdup("system");
flags["VPI_MODULE_LIST"] = vpi_module_list;
flags["-o"] = "a.out";
flags["-o"] = strdup("a.out");
min_typ_max_flag = TYP;
min_typ_max_warn = 10;
@ -933,6 +960,8 @@ int main(int argc, char*argv[])
<< endl;
}
delete des;
EOC_cleanup();
return 0;
errors_summary:

View File

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

View File

@ -2170,6 +2170,7 @@ int pform_parse(const char*path, FILE*file)
error_count += 1;
}
destroy_lexor();
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
* 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;
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)
{
/* 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",
path, name, stype);
}
fclose(fd);
return 0;
}

View File

@ -19,9 +19,6 @@
# include "vvp_priv.h"
# include <assert.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
# include <stdlib.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. */
# 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,
ivl_nexus_ptr_t omit_ptr, int omit_flags,
struct vvp_nexus_data*nex_data)
@ -515,8 +525,6 @@ char* draw_net_input_x(ivl_nexus_t nex,
unsigned idx;
int level;
unsigned ndrivers = 0;
static ivl_nexus_ptr_t *drivers = 0x0;
static unsigned adrivers = 0;
const char*resolv_type;

View File

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

View File

@ -1,7 +1,7 @@
#ifndef __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
* and/or modify it in source code form under the terms of the GNU
@ -141,6 +141,7 @@ struct vvp_nexus_data {
* cache it.
*/
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

View File

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