Skip to content
This repository
Browse code

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...
commit d98c925f53dc55bc6d0cdfb8111ae03d1f2bb250 1 parent f379cd0
Cary R. authored June 09, 2009 steveicarus committed June 19, 2009
30  StringHeap.cc
... ...
@@ -1,5 +1,5 @@
1 1
 /*
2  
- * Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com)
  2
+ * Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
3 3
  *
4 4
  *    This source code is free software; you can redistribute it
5 5
  *    and/or modify it in source code form under the terms of the GNU
@@ -25,6 +25,11 @@
25 25
 # include  <string.h>
26 26
 # include  <assert.h>
27 27
 
  28
+#ifdef CHECK_WITH_VALGRIND
  29
+static char **string_pool = NULL;
  30
+static unsigned string_pool_count = 0;
  31
+#endif
  32
+
28 33
 StringHeap::StringHeap()
29 34
 {
30 35
       cell_base_ = 0;
@@ -46,6 +51,12 @@ const char* StringHeap::add(const char*text)
46 51
       unsigned rem = HEAPCELL - cell_ptr_;
47 52
       if (rem < (len+1)) {
48 53
 	    cell_base_ = (char*)malloc(HEAPCELL);
  54
+#ifdef CHECK_WITH_VALGRIND
  55
+	    string_pool_count += 1;
  56
+	    string_pool = (char **) realloc(string_pool,
  57
+	                                    string_pool_count*sizeof(char **));
  58
+	    string_pool[string_pool_count-1] = cell_base_;
  59
+#endif
49 60
 	    cell_ptr_ = 0;
50 61
 	    cell_count_ += 1;
51 62
 	    assert(cell_base_ != 0);
@@ -80,6 +91,22 @@ StringHeapLex::~StringHeapLex()
80 91
 {
81 92
 }
82 93
 
  94
+void StringHeapLex::cleanup()
  95
+{
  96
+#ifdef CHECK_WITH_VALGRIND
  97
+      for (unsigned idx = 0 ;  idx < string_pool_count ;  idx += 1) {
  98
+	    free(string_pool[idx]);
  99
+      }
  100
+      free(string_pool);
  101
+      string_pool = NULL;
  102
+      string_pool_count = 0;
  103
+
  104
+      for (unsigned idx = 0 ;  idx < HASH_SIZE ;  idx += 1) {
  105
+	    hash_table_[idx] = 0;
  106
+      }
  107
+#endif
  108
+}
  109
+
83 110
 unsigned StringHeapLex::add_hit_count() const
84 111
 {
85 112
       return hit_count_;
@@ -175,4 +202,3 @@ bool operator < (perm_string a, perm_string b)
175 202
 
176 203
       return false;
177 204
 }
178  
-
3  StringHeap.h
... ...
@@ -1,7 +1,7 @@
1 1
 #ifndef __StringHeap_H
2 2
 #define __StringHeap_H
3 3
 /*
4  
- * Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com)
  4
+ * Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
5 5
  *
6 6
  *    This source code is free software; you can redistribute it
7 7
  *    and/or modify it in source code form under the terms of the GNU
@@ -104,6 +104,7 @@ class StringHeapLex  : private StringHeap {
104 104
 
105 105
       unsigned add_count() const;
106 106
       unsigned add_hit_count() const;
  107
+      void cleanup();
107 108
 
108 109
     private:
109 110
       enum { HASH_SIZE = 4096 };
1  compiler.h
@@ -202,5 +202,6 @@ struct sfunc_return_type {
202 202
 
203 203
 extern const struct sfunc_return_type* lookup_sys_func(const char*name);
204 204
 extern int load_sys_func_table(const char*path);
  205
+extern void cleanup_sys_func_table();
205 206
 
206 207
 #endif
8  config.h.in
... ...
@@ -1,7 +1,7 @@
1 1
 #ifndef __config_H                                           /* -*- c++ -*- */
2 2
 #define __config_H
3 3
 /*
4  
- * Copyright (c) 2001 Stephen Williams (steve@icarus.com)
  4
+ * Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
5 5
  *
6 6
  *    This source code is free software; you can redistribute it
7 7
  *    and/or modify it in source code form under the terms of the GNU
@@ -50,4 +50,10 @@
50 50
 # include  <inttypes.h>
51 51
 #endif
52 52
 
  53
+/*
  54
+ * Define this if you want to compile vvp with memory freeing and
  55
+ * special valgrind hooks for the memory pools.
  56
+ */
  57
+# undef CHECK_WITH_VALGRIND
  58
+
53 59
 #endif /* __config_H */
7  elaborate.cc
@@ -3786,14 +3786,12 @@ void PSpecPath::elaborate(Design*des, NetScope*scope) const
3786 3786
 
3787 3787
 	/* Do not elaborate specify delay paths if this feature is
3788 3788
 	   turned off. */
3789  
-      if (!gn_specify_blocks_flag)
3790  
-	    return;
  3789
+      if (!gn_specify_blocks_flag) return;
3791 3790
 
3792 3791
       ivl_assert(*this, conditional || (condition==0));
3793 3792
 
3794 3793
       ndelays = delays.size();
3795  
-      if (ndelays > 12)
3796  
-	    ndelays = 12;
  3794
+      if (ndelays > 12) ndelays = 12;
3797 3795
 
3798 3796
 	/* Print a warning if we find default and `timescale based
3799 3797
 	 * delays in the design, since this is likely an error. */
@@ -4453,6 +4451,7 @@ Design* elaborate(list<perm_string>roots)
4453 4451
 	    NetScope *scope = root_elems[i]->scope;
4454 4452
 
4455 4453
 	    rc &= rmod->elaborate(des, scope);
  4454
+	    delete root_elems[i];
4456 4455
       }
4457 4456
 
4458 4457
       if (rc == false) {
14  lexor.lex
@@ -1374,3 +1374,17 @@ void reset_lexor()
1374 1374
 	/* Announce the first file name. */
1375 1375
       yylloc.text = set_file_name(strdupnew(vl_file.c_str()));
1376 1376
 }
  1377
+
  1378
+/*
  1379
+ * Modern version of flex (>=2.5.9) can clean up the scanner data.
  1380
+ */
  1381
+void destroy_lexor()
  1382
+{
  1383
+# ifdef FLEX_SCANNER
  1384
+#   if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
  1385
+#     if defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
  1386
+    yylex_destroy();
  1387
+#     endif
  1388
+#   endif
  1389
+# endif
  1390
+}
37  main.cc
@@ -77,7 +77,7 @@ extern "C" const char*optarg;
77 77
 /* Count errors detected in flag processing. */
78 78
 unsigned flag_errors = 0;
79 79
 
80  
-const char*basedir = ".";
  80
+const char*basedir = strdup(".");
81 81
 
82 82
 /*
83 83
  * These are the language support control flags. These support which
@@ -280,7 +280,7 @@ static void parm_to_flagmap(const string&flag)
280 280
       unsigned off = flag.find('=');
281 281
       if (off > flag.size()) {
282 282
 	    key = flag;
283  
-	    value = "";
  283
+	    value = strdup("");
284 284
 
285 285
       } else {
286 286
 	    key = flag.substr(0, off);
@@ -399,6 +399,7 @@ static void read_iconfig_file(const char*ipath)
399 399
 	    }
400 400
 
401 401
 	    if (strcmp(buf, "basedir") == 0) {
  402
+		  free((char *)basedir);
402 403
 		  basedir = strdup(cp);
403 404
 
404 405
 	    } else if (strcmp(buf, "debug") == 0) {
@@ -472,6 +473,7 @@ static void read_iconfig_file(const char*ipath)
472 473
 		  flags["VPI_MODULE_LIST"] = vpi_module_list;
473 474
 
474 475
 	    } else if (strcmp(buf, "out") == 0) {
  476
+		  free((char *)flags["-o"]);
475 477
 		  flags["-o"] = strdup(cp);
476 478
 
477 479
 	    } else if (strcmp(buf, "sys_func") == 0) {
@@ -529,6 +531,7 @@ static void read_iconfig_file(const char*ipath)
529 531
 
530 532
 	    }
531 533
       }
  534
+      fclose(ifile);
532 535
 }
533 536
 
534 537
 extern Design* elaborate(list <perm_string> root);
@@ -555,6 +558,30 @@ inline static void times(struct tms *) { }
555 558
 inline static double cycles_diff(struct tms *a, struct tms *b) { return 0; }
556 559
 #endif // ! defined(HAVE_TIMES)
557 560
 
  561
+static void EOC_cleanup(void)
  562
+{
  563
+      cleanup_sys_func_table();
  564
+
  565
+      for (list<const char*>::iterator suf = library_suff.begin() ;
  566
+           suf != library_suff.end() ; suf ++ ) {
  567
+	    free((char *)*suf);
  568
+      }
  569
+      library_suff.clear();
  570
+
  571
+      free((char *) basedir);
  572
+      free(ivlpp_string);
  573
+      free(depfile_name);
  574
+
  575
+      for (map<string, const char*>::iterator flg = flags.begin() ;
  576
+           flg != flags.end() ; flg ++ ) {
  577
+	    free((char *)flg->second);
  578
+      }
  579
+      flags.clear();
  580
+
  581
+      lex_strings.cleanup();
  582
+      filename_strings.cleanup();
  583
+}
  584
+
558 585
 int main(int argc, char*argv[])
559 586
 {
560 587
       bool help_flag = false;
@@ -567,11 +594,11 @@ int main(int argc, char*argv[])
567 594
 
568 595
       struct tms cycles[5];
569 596
 
570  
-      library_suff.push_back(".v");
  597
+      library_suff.push_back(strdup(".v"));
571 598
 
572 599
       vpi_module_list = strdup("system");
573 600
       flags["VPI_MODULE_LIST"] = vpi_module_list;
574  
-      flags["-o"] = "a.out";
  601
+      flags["-o"] = strdup("a.out");
575 602
       min_typ_max_flag = TYP;
576 603
       min_typ_max_warn = 10;
577 604
 
@@ -933,6 +960,8 @@ int main(int argc, char*argv[])
933 960
 		 << endl;
934 961
       }
935 962
 
  963
+      delete des;
  964
+      EOC_cleanup();
936 965
       return 0;
937 966
 
938 967
  errors_summary:
2  parse_misc.h
@@ -60,6 +60,8 @@ extern void VLerror(const YYLTYPE&loc, const char*msg);
60 60
 #define yywarn VLwarn
61 61
 extern void VLwarn(const YYLTYPE&loc, const char*msg);
62 62
 
  63
+extern void destroy_lexor();
  64
+
63 65
 extern ostream& operator << (ostream&, const YYLTYPE&loc);
64 66
 
65 67
 extern unsigned error_count, warn_count;
1  pform.cc
@@ -2170,6 +2170,7 @@ int pform_parse(const char*path, FILE*file)
2170 2170
 	    error_count += 1;
2171 2171
       }
2172 2172
 
  2173
+      destroy_lexor();
2173 2174
       return error_count;
2174 2175
 }
2175 2176
 
14  sys_funcs.cc
... ...
@@ -1,5 +1,5 @@
1 1
 /*
2  
- * Copyright (c) 2004-2008 Stephen Williams (steve@icarus.com)
  2
+ * Copyright (c) 2004-2009 Stephen Williams (steve@icarus.com)
3 3
  *
4 4
  *    This source code is free software; you can redistribute it
5 5
  *    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 {
46 46
 
47 47
 static struct sfunc_return_type_cell*sfunc_stack = 0;
48 48
 
  49
+void cleanup_sys_func_table()
  50
+{
  51
+      struct sfunc_return_type_cell *next, *cur = sfunc_stack;
  52
+      while (cur) {
  53
+	    next = cur->next;
  54
+	    delete cur;
  55
+	    cur = next;
  56
+      }
  57
+}
  58
+
49 59
 const struct sfunc_return_type* lookup_sys_func(const char*name)
50 60
 {
51 61
 	/* First, try to find then name in the function stack. */
@@ -186,7 +196,7 @@ int load_sys_func_table(const char*path)
186 196
 	    fprintf(stderr, "%s:%s: Unknown type: %s\n",
187 197
 		    path, name, stype);
188 198
       }
  199
+      fclose(fd);
189 200
 
190 201
       return 0;
191 202
 }
192  
-
3  tgt-vvp/draw_mux.c
@@ -19,9 +19,6 @@
19 19
 
20 20
 # include  "vvp_priv.h"
21 21
 # include  <assert.h>
22  
-#ifdef HAVE_MALLOC_H
23  
-# include  <malloc.h>
24  
-#endif
25 22
 # include  <stdlib.h>
26 23
 # include  <string.h>
27 24
 
12  tgt-vvp/draw_net_input.c
@@ -505,6 +505,16 @@ static char* draw_island_port(ivl_island_t island,
505 505
   /* Omit LPMPART_BI device pin-data(0) drivers. */
506 506
 # define OMIT_PART_BI_DATA 0x0001
507 507
 
  508
+static ivl_nexus_ptr_t *drivers = 0x0;
  509
+static unsigned adrivers = 0;
  510
+
  511
+void EOC_cleanup_drivers()
  512
+{
  513
+      free(drivers);
  514
+      drivers = NULL;
  515
+      adrivers = 0;
  516
+}
  517
+
508 518
 char* draw_net_input_x(ivl_nexus_t nex,
509 519
 		       ivl_nexus_ptr_t omit_ptr, int omit_flags,
510 520
 		       struct vvp_nexus_data*nex_data)
@@ -515,8 +525,6 @@ char* draw_net_input_x(ivl_nexus_t nex,
515 525
       unsigned idx;
516 526
       int level;
517 527
       unsigned ndrivers = 0;
518  
-      static ivl_nexus_ptr_t *drivers = 0x0;
519  
-      static unsigned adrivers = 0;
520 528
 
521 529
       const char*resolv_type;
522 530
 
1  tgt-vvp/vvp.c
@@ -140,6 +140,7 @@ int target_design(ivl_design_t des)
140 140
       }
141 141
 
142 142
       fclose(vvp_out);
  143
+      EOC_cleanup_drivers();
143 144
 
144 145
       return rc + vvp_errors;
145 146
 }
3  tgt-vvp/vvp_priv.h
... ...
@@ -1,7 +1,7 @@
1 1
 #ifndef __vvp_priv_H
2 2
 #define __vvp_priv_H
3 3
 /*
4  
- * Copyright (c) 2001-2008 Stephen Williams (steve@icarus.com)
  4
+ * Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
5 5
  *
6 6
  *    This source code is free software; you can redistribute it
7 7
  *    and/or modify it in source code form under the terms of the GNU
@@ -141,6 +141,7 @@ struct vvp_nexus_data {
141 141
  * cache it.
142 142
  */
143 143
 extern const char* draw_net_input(ivl_nexus_t nex);
  144
+void EOC_cleanup_drivers();
144 145
 
145 146
 /*
146 147
  * See draw_net_input.c for details on draw_net_input_x. (It would be
32  tgt-vvp/vvp_scope.c
@@ -665,25 +665,12 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
665 665
       ivl_drive_t str0, str1;
666 666
 
667 667
       int level;
668  
-      int ninp = ivl_logic_pins(lptr) - 1;
669  
-      typedef const char*const_charp;
670  
-      const_charp*input_strings = calloc(ninp, sizeof(const_charp));
671  
-
672  
-      for (pdx = 0 ;  pdx < ninp ;  pdx += 1) {
673  
-	    ivl_nexus_t nex = ivl_logic_pin(lptr, pdx+1);
674  
-	    if (nex == 0) {
675  
-		    /* Only UDPs can have unconnected inputs. */
676  
-		  assert(ivl_logic_type(lptr) == IVL_LO_UDP);
677  
-		  input_strings[pdx] = 0;
678  
-	    } else {
679  
-		  input_strings[pdx] = draw_net_input(nex);
680  
-	    }
681  
-      }
  668
+      int ninp;
  669
+      const char **input_strings;
682 670
 
683 671
       switch (ivl_logic_type(lptr)) {
684 672
 
685 673
           case IVL_LO_UDP:
686  
-	    free(input_strings);
687 674
 	    draw_udp_in_scope(lptr);
688 675
 	    return;
689 676
 
@@ -706,7 +693,6 @@ static void draw_logic_in_scope(ivl_net_logic_t lptr)
706 693
 	      /* Skip pullup and pulldown objects. Things that have
707 694
 		 pull objects as inputs will instead generate the
708 695
 		 appropriate C<?> symbol. */
709  
-	    free(input_strings);
710 696
 	    return;
711 697
 
712 698
 	  case IVL_LO_AND:
@@ -1862,12 +1848,14 @@ int draw_scope(ivl_scope_t net, ivl_scope_t parent)
1862 1848
 		  fprintf(vvp_out, ">;\n");
1863 1849
 		  break;
1864 1850
 		case IVL_EX_REALNUM:
1865  
-		  fprintf(vvp_out, "P_%p .param/real \"%s\" %d %d, %s; value=%#g\n",
1866  
-			  par, ivl_parameter_basename(par),
1867  
-			  ivl_file_table_index(ivl_parameter_file(par)),
1868  
-			  ivl_parameter_lineno(par),
1869  
-			  draw_Cr_to_string(ivl_expr_dvalue(pex)),
1870  
-			  ivl_expr_dvalue(pex));
  1851
+		  { char *res = draw_Cr_to_string(ivl_expr_dvalue(pex));
  1852
+		    fprintf(vvp_out, "P_%p .param/real \"%s\" %d %d, %s; "
  1853
+		            "value=%#g\n", par, ivl_parameter_basename(par),
  1854
+			    ivl_file_table_index(ivl_parameter_file(par)),
  1855
+			    ivl_parameter_lineno(par), res,
  1856
+			    ivl_expr_dvalue(pex));
  1857
+		    free(res);
  1858
+		  }
1871 1859
 		  break;
1872 1860
 		default:
1873 1861
 		  fprintf(vvp_out, "; parameter type %d unsupported\n",

0 notes on commit d98c925

Please sign in to comment.
Something went wrong with that request. Please try again.