Permalink
Browse files

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.
  • Loading branch information...
caryr authored and steveicarus committed Jun 9, 2009
1 parent f379cd0 commit d98c925f53dc55bc6d0cdfb8111ae03d1f2bb250
Showing with 126 additions and 42 deletions.
  1. +28 −2 StringHeap.cc
  2. +2 −1 StringHeap.h
  3. +1 −0 compiler.h
  4. +7 −1 config.h.in
  5. +3 −4 elaborate.cc
  6. +14 −0 lexor.lex
  7. +33 −4 main.cc
  8. +2 −0 parse_misc.h
  9. +1 −0 pform.cc
  10. +12 −2 sys_funcs.cc
  11. +0 −3 tgt-vvp/draw_mux.c
  12. +10 −2 tgt-vvp/draw_net_input.c
  13. +1 −0 tgt-vvp/vvp.c
  14. +2 −1 tgt-vvp/vvp_priv.h
  15. +10 −22 tgt-vvp/vvp_scope.c
View
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+}
View
37 main.cc
@@ -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
@@ -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
@@ -2170,6 +2170,7 @@ int pform_parse(const char*path, FILE*file)
error_count += 1;
}
+ destroy_lexor();
return error_count;
}
View
@@ -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
@@ -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
@@ -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
@@ -140,6 +140,7 @@ int target_design(ivl_design_t des)
}
fclose(vvp_out);
+ EOC_cleanup_drivers();
return rc + vvp_errors;
}
View
@@ -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
Oops, something went wrong.

0 comments on commit d98c925

Please sign in to comment.