mirror of
https://github.com/verilator/verilator.git
synced 2025-01-06 06:37:45 +00:00
Fix memory leaks when using shared protect-lib (#2707)
* Guarantee mechanism to initialize just once is now in VerilatedInitializer. No functional change is intended. * Make sure to initialize Verilated::NonInitialized just once. Fixes memory leak in t_prot_lib_shared and t_hier_block_prot_lib_shared. * Call setup() and teardown() of Verilated::NonSerialized.
This commit is contained in:
parent
b75901b3eb
commit
738ee3d4eb
@ -72,10 +72,27 @@ Verilated::CommandArgValues Verilated::s_args;
|
||||
|
||||
VerilatedImp::VerilatedImpU VerilatedImp::s_s;
|
||||
|
||||
struct VerilatedImpInitializer {
|
||||
VerilatedImpInitializer() { VerilatedImp::setup(); }
|
||||
~VerilatedImpInitializer() { VerilatedImp::teardown(); }
|
||||
} s_VerilatedImpInitializer;
|
||||
// Guarantees to call setup() and teardown() just once.
|
||||
struct VerilatedInitializer {
|
||||
VerilatedInitializer() { setup(); }
|
||||
~VerilatedInitializer() { teardown(); }
|
||||
void setup() {
|
||||
static bool done = false;
|
||||
if (!done) {
|
||||
VerilatedImp::setup();
|
||||
Verilated::s_ns.setup();
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
void teardown() {
|
||||
static bool done = false;
|
||||
if (!done) {
|
||||
VerilatedImp::teardown();
|
||||
Verilated::s_ns.teardown();
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
} s_VerilatedInitializer;
|
||||
|
||||
//===========================================================================
|
||||
// User definable functions
|
||||
@ -261,10 +278,10 @@ Verilated::Serialized::Serialized() {
|
||||
s_timeprecision = VL_TIME_PRECISION; // Initial value until overriden by _Vconfigure
|
||||
}
|
||||
|
||||
Verilated::NonSerialized::NonSerialized() {
|
||||
void Verilated::NonSerialized::setup() {
|
||||
s_profThreadsFilenamep = strdup("profile_threads.dat");
|
||||
}
|
||||
Verilated::NonSerialized::~NonSerialized() {
|
||||
void Verilated::NonSerialized::teardown() {
|
||||
if (s_profThreadsFilenamep) {
|
||||
VL_DO_CLEAR(free(const_cast<char*>(s_profThreadsFilenamep)),
|
||||
s_profThreadsFilenamep = nullptr);
|
||||
@ -2478,21 +2495,13 @@ void Verilated::endOfEvalGuts(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
|
||||
//
|
||||
// To avoid the trouble, all member variables are enclosed in VerilatedImpU union.
|
||||
// ctor nor dtor of members are not called automatically.
|
||||
// VerilatedImp::setup() and teardown() guarantees to initialize/destruct just once.
|
||||
// VerilatedInitializer::setup() and teardown() guarantees to initialize/destruct just once.
|
||||
|
||||
void VerilatedImp::setup() {
|
||||
static bool done = false;
|
||||
if (!done) {
|
||||
new (&VerilatedImp::s_s) VerilatedImpData();
|
||||
done = true;
|
||||
}
|
||||
new (&VerilatedImp::s_s) VerilatedImpData();
|
||||
}
|
||||
void VerilatedImp::teardown() {
|
||||
static bool done = false;
|
||||
if (!done) {
|
||||
VerilatedImp::s_s.~VerilatedImpU();
|
||||
done = true;
|
||||
}
|
||||
VerilatedImp::s_s.~VerilatedImpU();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -399,8 +399,8 @@ class Verilated final {
|
||||
vluint32_t s_profThreadsWindow = 2; ///< +prof+threads window size
|
||||
// Slow path
|
||||
const char* s_profThreadsFilenamep; ///< +prof+threads filename
|
||||
NonSerialized();
|
||||
~NonSerialized();
|
||||
void setup();
|
||||
void teardown();
|
||||
} s_ns;
|
||||
|
||||
// no need to be save-restored (serialized) the
|
||||
@ -429,6 +429,8 @@ class Verilated final {
|
||||
} t_s;
|
||||
|
||||
private:
|
||||
friend struct VerilatedInitializer;
|
||||
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(Verilated);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user