diff --git a/SConstruct b/SConstruct index 3033348cd..eee1c78e8 100755 --- a/SConstruct +++ b/SConstruct @@ -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' ] diff --git a/src/base/fast_alloc.cc b/src/base/fast_alloc.cc index 649f94be3..0736d26e2 100644 --- a/src/base/fast_alloc.cc +++ b/src/base/fast_alloc.cc @@ -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 -#include -#include - -#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 typemap; - - for (FastAlloc *p = inUseHead.inUseNext; p != &inUseHead; p = p->inUseNext) - { - if (p->whenAllocated != 0) - ++typemap[typeid(*p).name()]; - } - - map::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 diff --git a/src/base/fast_alloc.hh b/src/base/fast_alloc.hh index 41f6f248c..58043e51e 100644 --- a/src/base/fast_alloc.hh +++ b/src/base/fast_alloc.hh @@ -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__