Internals: Add VL_ALLOC_RANDOM_CHECKS
This commit is contained in:
parent
230ce772c2
commit
e23c7a510e
|
|
@ -102,6 +102,7 @@ LIBS = $(CFG_LIBS) -lm
|
|||
CPPFLAGS += -DVERILATOR_INTERNAL_
|
||||
CPPFLAGS += -MMD
|
||||
CPPFLAGS += -I. -I$(bldsrc) -I$(srcdir) -I$(incdir) -I../../include
|
||||
#CPPFLAGS += -DVL_ALLOC_RANDOM_CHECKS # To allow --debug-new-random
|
||||
#CPPFLAGS += -DVL_LEAK_CHECKS # If running valgrind or other hunting tool
|
||||
CPPFLAGS += -MP # Only works on recent GCC versions
|
||||
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@
|
|||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef VL_ALLOC_RANDOM_CHECKS
|
||||
#include "V3Ast__gen_sizeof.h"
|
||||
#endif
|
||||
|
||||
VL_DEFINE_DEBUG_FUNCTIONS;
|
||||
|
||||
//======================================================================
|
||||
|
|
@ -992,6 +996,43 @@ void AstNode::operator delete(void* objp, size_t size) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef VL_ALLOC_RANDOM_CHECKS
|
||||
void* AstNode::operator new(size_t size) {
|
||||
// Make the following small to debug this routine, larger for performance and better random
|
||||
constexpr size_t POOL_SIZE = 65536; // Ideally large enough to fit all nodes used in tests
|
||||
// Randomly select from a large pool (POOL_SIZE) of max-node sized (MAX_NODE_SIZE) pointers
|
||||
static uint64_t s_lfsr = 0; // LFSR, 0 = didn't initialize yet
|
||||
static std::array<void*, POOL_SIZE> s_nodePool;
|
||||
if (int seed = v3Global.opt.debugAllocRandom()) {
|
||||
constexpr uint64_t POLYNOMIAL = 0x80000000000019e2ULL;
|
||||
UASSERT_STATIC(size <= ASTGEN_MAX_NODE_SIZE, "fix ASTGEN_MAX_NODE_SIZE");
|
||||
if (!s_lfsr) {
|
||||
s_lfsr = seed;
|
||||
if (!s_lfsr) s_lfsr = ~s_lfsr;
|
||||
for (size_t i = 0; i < POOL_SIZE; ++i) {
|
||||
s_nodePool[i] = ::operator new(ASTGEN_MAX_NODE_SIZE + 64);
|
||||
}
|
||||
// Sort, just to make it more obvious we are properly randomizing
|
||||
std::sort(std::begin(s_nodePool), std::end(s_nodePool));
|
||||
}
|
||||
// Xoroshiro128+ algorithm
|
||||
s_lfsr = (s_lfsr & 1ULL) ? ((s_lfsr >> 1ULL) ^ POLYNOMIAL) : (s_lfsr >> 1ULL);
|
||||
const size_t index = s_lfsr % POOL_SIZE;
|
||||
AstNode* const objp = static_cast<AstNode*>(s_nodePool[index]);
|
||||
s_nodePool[index] = ::operator new(ASTGEN_MAX_NODE_SIZE + 64); // For later new()
|
||||
return objp;
|
||||
} else {
|
||||
AstNode* const objp = static_cast<AstNode*>(::operator new(size));
|
||||
return objp;
|
||||
}
|
||||
}
|
||||
void AstNode::operator delete(void* objp, size_t size) {
|
||||
// Leak due to size difference between true node and MAX_NODE_SIZE
|
||||
(void)objp;
|
||||
(void)size;
|
||||
}
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
// Iterators
|
||||
|
||||
|
|
|
|||
|
|
@ -560,7 +560,7 @@ public:
|
|||
// Perform a function on every link in a node
|
||||
virtual void foreachLink(std::function<void(AstNode** linkpp, const char* namep)> f) = 0;
|
||||
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
#if defined(VL_LEAK_CHECKS) || defined(VL_ALLOC_RANDOM_CHECKS)
|
||||
static void* operator new(size_t size);
|
||||
static void operator delete(void* obj, size_t size);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1375,6 +1375,9 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
DECL_OPTION("-debug-abort", CbCall, []() {
|
||||
V3Error::vlAbort(); // LCOV_EXCL_LINE
|
||||
}).undocumented(); // See also --debug-sigseg
|
||||
#ifdef VL_ALLOC_RANDOM_CHECKS
|
||||
DECL_OPTION("-debug-alloc-random", Set, &m_debugAllocRandom).undocumented();
|
||||
#endif
|
||||
DECL_OPTION("-debug-check", OnOff, &m_debugCheck);
|
||||
DECL_OPTION("-debug-collision", OnOff, &m_debugCollision).undocumented();
|
||||
DECL_OPTION("-debug-emitv", OnOff, &m_debugEmitV).undocumented();
|
||||
|
|
|
|||
|
|
@ -315,6 +315,7 @@ private:
|
|||
int m_coverageExprMax = 32; // main switch: --coverage-expr-max
|
||||
int m_convergeLimit = 100; // main switch: --converge-limit
|
||||
int m_coverageMaxWidth = 256; // main switch: --coverage-max-width
|
||||
int m_debugAllocRandom = 0; // main switch: --debug-alloc-random <seed>
|
||||
int m_expandLimit = 256; // main switch: --expand-limit
|
||||
int m_gateStmts = 100; // main switch: --gate-stmts
|
||||
int m_hierChild = 0; // main switch: --hierarchical-child
|
||||
|
|
@ -597,6 +598,7 @@ public:
|
|||
int convergeLimit() const { return m_convergeLimit; }
|
||||
int coverageExprMax() const { return m_coverageExprMax; }
|
||||
int coverageMaxWidth() const { return m_coverageMaxWidth; }
|
||||
int debugAllocRandom() const { return m_debugAllocRandom; }
|
||||
bool dumpTreeAddrids() const VL_MT_SAFE;
|
||||
int expandLimit() const { return m_expandLimit; }
|
||||
int gateStmts() const { return m_gateStmts; }
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ public:
|
|||
m_classOrPackagep = reinterpret_cast<AstNodeModule*>(1);
|
||||
#endif
|
||||
}
|
||||
#if defined(VL_DEBUG) && !defined(VL_LEAK_CHECKS)
|
||||
#if (defined(VL_DEBUG) || defined(VL_ALLOC_RANDOM_CHECKS)) && !defined(VL_LEAK_CHECKS)
|
||||
// For testing, leak so above destructor 1 assignments work
|
||||
void* operator new(size_t size) { return std::malloc(size); }
|
||||
void operator delete(void* objp, size_t size) {}
|
||||
|
|
|
|||
11
src/astgen
11
src/astgen
|
|
@ -935,6 +935,16 @@ def write_ast_type_info(filename):
|
|||
))
|
||||
|
||||
|
||||
def write_ast_sizeof(filename):
|
||||
with open_file(filename) as fh:
|
||||
fh.write("static constexpr size_t ASTGEN_MAX_NODE_SIZE =\n")
|
||||
paren = ""
|
||||
for node in AstNodeList:
|
||||
fh.write(" std::max(sizeof(Ast{n}),\n".format(n=node.name))
|
||||
paren += ")"
|
||||
fh.write(" static_cast<size_t>(0)" + paren + ";\n")
|
||||
|
||||
|
||||
def write_ast_impl(filename):
|
||||
with open_file(filename) as fh:
|
||||
|
||||
|
|
@ -1584,6 +1594,7 @@ if Args.classes:
|
|||
write_ast_impl("V3Ast__gen_impl.h")
|
||||
write_ast_macros("V3Ast__gen_macros.h")
|
||||
write_ast_yystype("V3Ast__gen_yystype.h")
|
||||
write_ast_sizeof("V3Ast__gen_sizeof.h")
|
||||
# Write Dfg code
|
||||
write_forward_class_decls("Dfg", DfgVertexList)
|
||||
write_visitor_decls("Dfg", DfgVertexList)
|
||||
|
|
|
|||
Loading…
Reference in New Issue