From ff82f75023c20eedd93777759ebab40d461da270 Mon Sep 17 00:00:00 2001 From: John Coiner Date: Sat, 10 Mar 2018 12:18:19 -0500 Subject: [PATCH] Add --no-debug-leak to reduce memory use under debug. --- Changes | 2 ++ bin/verilator | 13 +++++++++++++ src/V3Ast.cpp | 10 +++++++++- src/V3Options.cpp | 2 ++ src/V3Options.h | 2 ++ test_regress/t/t_flag_debug_noleak.pl | 20 ++++++++++++++++++++ test_regress/t/t_flag_debug_noleak.v | 12 ++++++++++++ 7 files changed, 60 insertions(+), 1 deletion(-) create mode 100755 test_regress/t/t_flag_debug_noleak.pl create mode 100644 test_regress/t/t_flag_debug_noleak.v diff --git a/Changes b/Changes index 659bca130..fe52b438d 100644 --- a/Changes +++ b/Changes @@ -8,6 +8,8 @@ The contributors that suggested a given feature are shown in []. Thanks! *** Support calling system functions as tasks, bug1285. [Joel Holdsworth] +*** Add --no-debug-leak to reduce memory use under debug. [John Coiner] + **** Fix GCC 8.0 issues, bug1273. **** Fix pullup/pulldowns on bit selects, bug1274. [Rob Stoddard] diff --git a/bin/verilator b/bin/verilator index 618216542..4b17cdaf3 100755 --- a/bin/verilator +++ b/bin/verilator @@ -278,6 +278,7 @@ descriptions in the next sections for more information. -D[=] Set preprocessor define --debug Enable debugging --debug-check Enable debugging assertions + --no-debug-leak Disable leaking memory in --debug mode --debugi Enable debugging at a specified level --debugi- Enable debugging a source file at a level --default-language Default language to parse @@ -635,6 +636,18 @@ to C<--dump-treei 3>). Rarely needed. Enable internal debugging assertion checks, without changing debug verbosity. Enabled automatically when --debug specified. +=item --no-debug-leak + +In --debug mode, by default Verilator intentionally leaks AstNode's +instead of freeing them, so that each node pointer is unique in the +resulting tree files and dot files. + +This option disables the leak. This may avoid out-of-memory errors +when Verilating large models in --debug mode. + +Outside of --debug mode, AstNode's should never be leaked and this option +has no effect. + =item --debugi =item --debugi- diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 8b8d7e863..688ca5942 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -677,9 +677,17 @@ void AstNode::deleteNode() { this->m_op2p = (AstNode*)1; this->m_op3p = (AstNode*)1; this->m_op4p = (AstNode*)1; + if ( #if !defined(VL_DEBUG) || defined(VL_LEAK_CHECKS) - delete this; // Leak massively, so each pointer is unique and we can debug easier + 1 +#else + !v3Global.opt.debugLeak() #endif + ) { + delete this; + } + // Else leak massively, so each pointer is unique + // and we can debug easier. } AstNode::~AstNode() { diff --git a/src/V3Options.cpp b/src/V3Options.cpp index ef3b7d41a..aba146712 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -659,6 +659,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char else if ( onoff (sw, "-covsp", flag/*ref*/) ) { } // TBD else if ( !strcmp (sw, "-debug-abort") ) { abort(); } // Undocumented, see also --debug-sigsegv else if ( onoff (sw, "-debug-check", flag/*ref*/) ){ m_debugCheck = flag; } + else if ( onoff (sw, "-debug-leak", flag/*ref*/) ){ m_debugLeak = flag; } else if ( !strcmp (sw, "-debug-sigsegv") ) { throwSigsegv(); } // Undocumented, see also --debug-abort else if ( !strcmp (sw, "-debug-fatalsrc") ) { v3fatalSrc("--debug-fatal-src"); } // Undocumented, see also --debug-abort else if ( onoff (sw, "-decoration", flag/*ref*/) ) { m_decoration = flag; } @@ -1218,6 +1219,7 @@ V3Options::V3Options() { m_coverageUnderscore = false; m_coverageUser = false; m_debugCheck = false; + m_debugLeak = true; m_decoration = true; m_exe = false; m_ignc = false; diff --git a/src/V3Options.h b/src/V3Options.h index de2996915..23352d284 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -75,6 +75,7 @@ class V3Options { bool m_coverageUnderscore;// main switch: --coverage-underscore bool m_coverageUser; // main switch: --coverage-func bool m_debugCheck; // main switch: --debug-check + bool m_debugLeak; // main switch: --debug-leak bool m_decoration; // main switch: --decoration bool m_exe; // main switch: --exe bool m_ignc; // main switch: --ignc @@ -229,6 +230,7 @@ class V3Options { bool coverageUnderscore() const { return m_coverageUnderscore; } bool coverageUser() const { return m_coverageUser; } bool debugCheck() const { return m_debugCheck; } + bool debugLeak() const { return m_debugLeak; } bool decoration() const { return m_decoration; } bool exe() const { return m_exe; } bool trace() const { return m_trace; } diff --git a/test_regress/t/t_flag_debug_noleak.pl b/test_regress/t/t_flag_debug_noleak.pl new file mode 100755 index 000000000..97e7d9366 --- /dev/null +++ b/test_regress/t/t_flag_debug_noleak.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2008 by Wilson Snyder. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. + +$Self->{vlt} or $Self->skip("Verilator only test"); + +compile ( + v_flags2 => ["--debug --no-debug-leak"], + verilator_make_gcc => 0, + make_top_shell => 0, + make_main => 0, + ); + +ok(1); +1; diff --git a/test_regress/t/t_flag_debug_noleak.v b/test_regress/t/t_flag_debug_noleak.v new file mode 100644 index 000000000..92add3b4e --- /dev/null +++ b/test_regress/t/t_flag_debug_noleak.v @@ -0,0 +1,12 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2008 by Wilson Snyder. + +module t; + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule +