base: disable FastAlloc in debug builds by default
FastAlloc's reuse policies can mask allocation bugs, so we typically want it disabled when debugging. Set FORCE_FAST_ALLOC to enable even when debugging, and set NO_FAST_ALLOC to disable even in non-debug builds.
This commit is contained in:
parent
6daf44dae6
commit
38aa50bb49
3 changed files with 16 additions and 189 deletions
|
@ -822,8 +822,8 @@ sticky_vars.AddVariables(
|
|||
sorted(n for n,m in CpuModel.dict.iteritems() if m.default),
|
||||
sorted(CpuModel.list)),
|
||||
BoolVariable('NO_FAST_ALLOC', 'Disable fast object allocator', False),
|
||||
BoolVariable('FAST_ALLOC_DEBUG', 'Enable fast object allocator debugging',
|
||||
False),
|
||||
BoolVariable('FORCE_FAST_ALLOC',
|
||||
'Enable fast object allocator, even for m5.debug', False),
|
||||
BoolVariable('FAST_ALLOC_STATS', 'Enable fast object allocator statistics',
|
||||
False),
|
||||
BoolVariable('EFENCE', 'Link with Electric Fence malloc debugger',
|
||||
|
@ -844,7 +844,7 @@ sticky_vars.AddVariables(
|
|||
|
||||
# These variables get exported to #defines in config/*.hh (see src/SConscript).
|
||||
export_vars += ['FULL_SYSTEM', 'USE_FENV', 'USE_MYSQL',
|
||||
'NO_FAST_ALLOC', 'FAST_ALLOC_DEBUG', 'FAST_ALLOC_STATS',
|
||||
'NO_FAST_ALLOC', 'FORCE_FAST_ALLOC', 'FAST_ALLOC_STATS',
|
||||
'SS_COMPATIBLE_FP', 'USE_CHECKER', 'TARGET_ISA', 'CP_ANNOTATE',
|
||||
'USE_POSIX_CLOCK' ]
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include "base/fast_alloc.hh"
|
||||
|
||||
#if !NO_FAST_ALLOC
|
||||
#if USE_FAST_ALLOC
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
|
@ -73,156 +73,4 @@ FastAlloc::moreStructs(int bucket)
|
|||
return (p + sz);
|
||||
}
|
||||
|
||||
#if FAST_ALLOC_DEBUG
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
|
||||
#include "base/cprintf.hh"
|
||||
#include "sim/core.hh" // for curTick()
|
||||
|
||||
using namespace std;
|
||||
|
||||
// count of in-use FastAlloc objects
|
||||
int FastAlloc::numInUse;
|
||||
|
||||
// dummy head & tail object for doubly linked list of in-use FastAlloc
|
||||
// objects
|
||||
FastAlloc FastAlloc::inUseHead(&FastAlloc::inUseHead, &FastAlloc::inUseHead);
|
||||
|
||||
// special constructor for dummy head: make inUsePrev & inUseNext
|
||||
// point to self
|
||||
FastAlloc::FastAlloc(FastAlloc *prev, FastAlloc *next)
|
||||
{
|
||||
inUsePrev = prev;
|
||||
inUseNext = next;
|
||||
}
|
||||
|
||||
// constructor: marks as in use, add to in-use list
|
||||
FastAlloc::FastAlloc()
|
||||
{
|
||||
// mark this object in use
|
||||
inUse = true;
|
||||
whenAllocated = curTick();
|
||||
|
||||
// update count
|
||||
++numInUse;
|
||||
|
||||
// add to tail of list of in-use objects ("before" dummy head)
|
||||
FastAlloc *myNext = &inUseHead;
|
||||
FastAlloc *myPrev = inUseHead.inUsePrev;
|
||||
|
||||
inUsePrev = myPrev;
|
||||
inUseNext = myNext;
|
||||
myPrev->inUseNext = this;
|
||||
myNext->inUsePrev = this;
|
||||
}
|
||||
|
||||
// destructor: mark not in use, remove from in-use list
|
||||
FastAlloc::~FastAlloc()
|
||||
{
|
||||
assert(inUse);
|
||||
inUse = false;
|
||||
|
||||
--numInUse;
|
||||
assert(numInUse >= 0);
|
||||
|
||||
// remove me from in-use list
|
||||
inUsePrev->inUseNext = inUseNext;
|
||||
inUseNext->inUsePrev = inUsePrev;
|
||||
}
|
||||
|
||||
|
||||
// Note that in all the display functions below we suppress anything
|
||||
// with a zero allocation timestamp... there are a bunch of static or
|
||||
// quasi-static structures that get allocated during initialization
|
||||
// and we generally don't care about them so this gets them out of the
|
||||
// way.
|
||||
|
||||
// summarize in-use list
|
||||
void
|
||||
FastAlloc::dump_summary()
|
||||
{
|
||||
map<string, int> typemap;
|
||||
|
||||
for (FastAlloc *p = inUseHead.inUseNext; p != &inUseHead; p = p->inUseNext)
|
||||
{
|
||||
if (p->whenAllocated != 0)
|
||||
++typemap[typeid(*p).name()];
|
||||
}
|
||||
|
||||
map<string, int>::const_iterator mapiter;
|
||||
|
||||
cprintf(" count type\n"
|
||||
" ----- ----\n");
|
||||
for (mapiter = typemap.begin(); mapiter != typemap.end(); ++mapiter)
|
||||
cprintf("%6d %s\n",mapiter->second, mapiter->first);
|
||||
}
|
||||
|
||||
|
||||
// show oldest n items on in-use list
|
||||
void
|
||||
FastAlloc::dump_oldest(int n)
|
||||
{
|
||||
// sanity check: don't want to crash the debugger if you forget to
|
||||
// pass in a parameter
|
||||
if (n < 0 || n > numInUse) {
|
||||
cprintf("FastAlloc::dump_oldest: bad arg %d (%d objects in use)\n",
|
||||
n, numInUse);
|
||||
return;
|
||||
}
|
||||
|
||||
for (FastAlloc *p = inUseHead.inUseNext;
|
||||
p != &inUseHead && n > 0;
|
||||
p = p->inUseNext, --n) {
|
||||
if (p->whenAllocated != 0)
|
||||
cprintf("%x %15d %s\n", p, p->whenAllocated, typeid(*p).name());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// show oldest n items on in-use list for specified type
|
||||
void
|
||||
FastAlloc::dump_oldest_of_type(int n, const char *type_name)
|
||||
{
|
||||
// sanity check: don't want to crash the debugger if you forget to
|
||||
// pass in a parameter
|
||||
if (n < 0 || n > numInUse) {
|
||||
cprintf("FastAlloc::dump_oldest_of_type: bad arg %d "
|
||||
"(%d objects in use)\n",
|
||||
n, numInUse);
|
||||
return;
|
||||
}
|
||||
|
||||
for (FastAlloc *p = inUseHead.inUseNext;
|
||||
p != &inUseHead && n > 0;
|
||||
p = p->inUseNext) {
|
||||
if (p->whenAllocated != 0 &&
|
||||
strcmp(typeid(*p).name(), type_name) == 0) {
|
||||
cprintf("%x %15d\n", p, p->whenAllocated);
|
||||
--n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C interfaces to FastAlloc::dump_summary() and FastAlloc::dump_oldest().
|
||||
// gdb seems to have trouble with calling C++ functions directly.
|
||||
//
|
||||
void
|
||||
fast_alloc_summary()
|
||||
{
|
||||
FastAlloc::dump_summary();
|
||||
}
|
||||
|
||||
void
|
||||
fast_alloc_oldest(int n)
|
||||
{
|
||||
FastAlloc::dump_oldest(n);
|
||||
}
|
||||
|
||||
#endif // FAST_ALLOC_DEBUG
|
||||
|
||||
#endif // NO_FAST_ALLOC
|
||||
#endif // USE_FAST_ALLOC
|
||||
|
|
|
@ -63,10 +63,18 @@
|
|||
// hierarchy.
|
||||
|
||||
#include "config/no_fast_alloc.hh"
|
||||
#include "config/fast_alloc_debug.hh"
|
||||
#include "config/force_fast_alloc.hh"
|
||||
#include "config/fast_alloc_stats.hh"
|
||||
|
||||
#if NO_FAST_ALLOC
|
||||
// By default, we want to enable FastAlloc in any build other than
|
||||
// m5.debug. (FastAlloc's reuse policies can mask allocation bugs, so
|
||||
// we typically want it disabled when debugging.) Set
|
||||
// FORCE_FAST_ALLOC to enable even when debugging, and set
|
||||
// NO_FAST_ALLOC to disable even in non-debug builds.
|
||||
#define USE_FAST_ALLOC \
|
||||
(FORCE_FAST_ALLOC || (!defined(DEBUG) && !NO_FAST_ALLOC))
|
||||
|
||||
#if !USE_FAST_ALLOC
|
||||
|
||||
class FastAlloc
|
||||
{
|
||||
|
@ -74,10 +82,6 @@ class FastAlloc
|
|||
|
||||
#else
|
||||
|
||||
#if FAST_ALLOC_DEBUG
|
||||
#include "base/types.hh"
|
||||
#endif
|
||||
|
||||
class FastAlloc
|
||||
{
|
||||
public:
|
||||
|
@ -87,13 +91,7 @@ class FastAlloc
|
|||
void *operator new(size_t);
|
||||
void operator delete(void *, size_t);
|
||||
|
||||
#if FAST_ALLOC_DEBUG
|
||||
FastAlloc();
|
||||
FastAlloc(FastAlloc *, FastAlloc *); // for inUseHead, see below
|
||||
virtual ~FastAlloc();
|
||||
#else
|
||||
virtual ~FastAlloc() {}
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
|
@ -125,25 +123,6 @@ class FastAlloc
|
|||
static unsigned deleteCount[Num_Buckets];
|
||||
static unsigned allocCount[Num_Buckets];
|
||||
#endif
|
||||
|
||||
#if FAST_ALLOC_DEBUG
|
||||
// per-object debugging fields
|
||||
bool inUse; // in-use flag
|
||||
FastAlloc *inUsePrev; // ptrs to build list of in-use objects
|
||||
FastAlloc *inUseNext;
|
||||
Tick whenAllocated;
|
||||
|
||||
// static (global) debugging vars
|
||||
static int numInUse; // count in-use objects
|
||||
static FastAlloc inUseHead; // dummy head for list of in-use objects
|
||||
|
||||
public:
|
||||
// functions to dump debugging info (see fast_alloc.cc for C
|
||||
// versions that might be more agreeable to call from gdb)
|
||||
static void dump_summary();
|
||||
static void dump_oldest(int n);
|
||||
static void dump_oldest_of_type(int n, const char *type_name);
|
||||
#endif
|
||||
};
|
||||
|
||||
inline int
|
||||
|
@ -206,6 +185,6 @@ FastAlloc::operator delete(void *p, size_t sz)
|
|||
deallocate(p, sz);
|
||||
}
|
||||
|
||||
#endif // NO_FAST_ALLOC
|
||||
#endif // USE_FAST_ALLOC
|
||||
|
||||
#endif // __BASE_FAST_ALLOC_HH__
|
||||
|
|
Loading…
Reference in a new issue