Fix some memory leaks in V3Const/V3Unroll.

This commit is contained in:
Wilson Snyder 2019-05-29 22:43:26 -04:00
parent 72eb361131
commit 8846b365f4
4 changed files with 33 additions and 9 deletions

View File

@ -74,7 +74,7 @@ public:
// Called by operator new on any node - only if VL_LEAK_CHECKS
if (debug()>=9) cout<<"-nodeNew: "<<cvtToHex(nodep)<<endl;
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter!=s_nodes.end() || (iter->second & FLAG_ALLOCATED)) {
if (iter !=s_nodes.end() && (iter->second & FLAG_ALLOCATED)) {
nodep->v3fatalSrc("Newing AstNode object that is already allocated");
}
if (iter == s_nodes.end()) {
@ -117,8 +117,18 @@ public:
iter->second |= or_flags;
}
}
static bool isAllocated(const AstNode* nodep) {
// Some generic node has a pointer to this node. Is it allocated?
// Use this when might not be in tree; otherwise use okIfLinkedTo().
#ifdef VL_LEAK_CHECKS
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter == s_nodes.end()) return false;
if (!(iter->second & FLAG_ALLOCATED)) return false;
#endif
return true;
}
static bool okIfLinkedTo(const AstNode* nodep) {
// Someone has a pointer to this node. Is it kosher?
// Some node in tree has a pointer to this node. Is it kosher?
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter == s_nodes.end()) return false;
#ifdef VL_LEAK_CHECKS
@ -155,6 +165,11 @@ public:
// Use only AstNode::dump instead of the virtual one, as there
// may be varp() and other cross links that are bad.
if (v3Global.opt.debugCheck()) {
// When get this message, find what forgot to delete the
// node by running GDB, where for node "<e###>" use:
// watch AstNode::s_editCntGbl==####
// run
// bt
std::cerr<<"%Error: LeakedNode"<<(it->first->backp()?"Back: ":": ");
AstNode* rawp = const_cast<AstNode*>
(static_cast<const AstNode*>(it->first));
@ -295,3 +310,6 @@ void V3Broken::addNewed(AstNode* nodep) {
void V3Broken::deleted(AstNode* nodep) {
BrokenTable::deleted(nodep);
}
bool V3Broken::isAllocated(AstNode* nodep) {
return BrokenTable::isAllocated(nodep);
}

View File

@ -34,6 +34,7 @@ public:
static void brokenAll(AstNetlist* nodep);
static void addNewed(AstNode* nodep);
static void deleted(AstNode* nodep);
static bool isAllocated(AstNode* nodep);
};
#endif // Guard

View File

@ -1540,6 +1540,7 @@ private:
fromp->dtypeFrom(VN_CAST(fromp->dtypep()->skipRefp(),
NodeArrayDType)->subDTypep());
}
nodep->deleteTree(); VL_DANGLING(nodep);
}
}
m_selp = NULL;

View File

@ -189,44 +189,48 @@ private:
bool simulateTree(AstNode *nodep, const V3Number *loopValue,
AstNode *dtypep, V3Number &outNum) {
AstNode* clone = nodep->cloneTree(true);
if (!clone) {
AstNode* clonep = nodep->cloneTree(true);
if (!clonep) {
nodep->v3fatalSrc("Failed to clone tree");
return false;
}
if (loopValue) {
m_varValuep = new AstConst(nodep->fileline(), *loopValue);
// Iteration requires a back, so put under temporary node
AstBegin* tempp = new AstBegin(nodep->fileline(), "[EditWrapper]", clone);
AstBegin* tempp = new AstBegin(nodep->fileline(), "[EditWrapper]", clonep);
m_varModeReplace = true;
iterateAndNextNull(tempp->stmtsp());
m_varModeReplace = false;
clone = tempp->stmtsp()->unlinkFrBackWithNext();
clonep = tempp->stmtsp()->unlinkFrBackWithNext();
tempp->deleteTree();
tempp = NULL;
pushDeletep(m_varValuep); m_varValuep = NULL;
}
SimulateVisitor simvis;
simvis.mainParamEmulate(clone);
simvis.mainParamEmulate(clonep);
if (!simvis.optimizable()) {
UINFO(3, "Unable to simulate" << endl);
if (debug()>=9) nodep->dumpTree(cout, "- _simtree: ");
clonep->deleteTree(); VL_DANGLING(clonep);
return false;
}
// Fetch the result
V3Number* res = simvis.fetchNumberNull(clone);
V3Number* res = simvis.fetchNumberNull(clonep);
if (!res) {
UINFO(3, "No number returned from simulation" << endl);
clonep->deleteTree(); VL_DANGLING(clonep);
return false;
}
// Patch up datatype
if (dtypep) {
AstConst new_con (clone->fileline(), *res);
AstConst new_con (clonep->fileline(), *res);
new_con.dtypeFrom(dtypep);
outNum = new_con.num();
clonep->deleteTree(); VL_DANGLING(clonep);
return true;
}
outNum = *res;
clonep->deleteTree(); VL_DANGLING(clonep);
return true;
}