base: disable FastAlloc in debug builds by default
authorSteve Reinhardt <steve.reinhardt@amd.com>
Fri, 18 Mar 2011 18:47:11 +0000 (11:47 -0700)
committerSteve Reinhardt <steve.reinhardt@amd.com>
Fri, 18 Mar 2011 18:47:11 +0000 (11:47 -0700)
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.

SConstruct
src/base/fast_alloc.cc
src/base/fast_alloc.hh

index 3033348cd7e439a8dafa9e3a71a3273090e1e2de..eee1c78e87762adb461f9a638adab1c3f0612749 100755 (executable)
@@ -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' ]
 
index 649f94be39d457ac7e908544d0f5da3cab1e4052..0736d26e2dfddb81c91af112b866187f1e015a63 100644 (file)
@@ -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
index 41f6f248ce0cb325f9abed0c442d22eab3dc72ce..58043e51e6b19f99fa09e4c8085ef58e813ed296 100644 (file)
 // 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__