gem5/base/fast_alloc.hh
Steve Reinhardt c4793184bd Build options are set via a build_options file in the
build directory instead of being inferred from the name
of the build directory.
Options are passed to C++ via config/*.hh files instead of
via the command line.  Build option flags are now always
defined to 0 or 1, so checks must use '#if' rather than
'#ifdef'.

SConscript:
    MySQL detection moved to SConstruct.
    Add config/*.hh files (via ConfigFile builder).
arch/alpha/alpha_memory.cc:
arch/alpha/ev5.cc:
arch/alpha/ev5.hh:
arch/alpha/isa_traits.hh:
base/fast_alloc.hh:
base/statistics.cc:
base/statistics.hh:
base/stats/events.cc:
base/stats/events.hh:
cpu/base.cc:
cpu/base.hh:
cpu/base_dyn_inst.cc:
cpu/base_dyn_inst.hh:
cpu/exec_context.cc:
cpu/exec_context.hh:
cpu/o3/alpha_cpu.hh:
cpu/o3/alpha_cpu_builder.cc:
cpu/o3/alpha_cpu_impl.hh:
cpu/o3/alpha_dyn_inst.hh:
cpu/o3/alpha_dyn_inst_impl.hh:
cpu/o3/alpha_params.hh:
cpu/o3/commit_impl.hh:
cpu/o3/cpu.cc:
cpu/o3/cpu.hh:
cpu/o3/fetch_impl.hh:
cpu/o3/iew.hh:
cpu/o3/iew_impl.hh:
cpu/o3/regfile.hh:
cpu/o3/rename_impl.hh:
cpu/o3/rob_impl.hh:
cpu/ozone/cpu.hh:
cpu/pc_event.cc:
cpu/simple/cpu.cc:
cpu/simple/cpu.hh:
sim/process.cc:
sim/process.hh:
    Convert compile flags from def/undef to 0/1.
    Set via #include config/*.hh instead of command line.
arch/alpha/isa_desc:
    Convert compile flags from def/undef to 0/1.
    Set via #include config/*.hh instead of command line.
    Revamp fenv.h support... most of the ugliness is hidden
    in base/fenv.hh now.
base/mysql.hh:
    Fix typo in #ifndef guard.
build/SConstruct:
    Build options are set via a build_options file in the
    build directory instead of being inferred from the name
    of the build directory.
    Options are passed to C++ via config/*.hh files instead of
    via the command line.
python/SConscript:
    Generate m5_build_env directly from scons options
    instead of indirectly via CPPDEFINES.
python/m5/convert.py:
    Allow '0' and '1' for booleans.
    Rewrite toBool to use dict.
base/fenv.hh:
    Revamp <fenv.h> support to make it a compile option
    (so we can test w/o it even if it's present) and to
    make isa_desc cleaner.

--HG--
extra : convert_revision : 8f97dc11185bef5e1865b3269c7341df8525c9ad
2005-08-30 13:18:54 -04:00

214 lines
6.2 KiB
C++

/*
* Copyright (c) 2000-2001, 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This code was originally written by Steve Reinhardt as part of
* the Wisconsin Wind Tunnel simulator. Relicensed as part of M5
* by permission.
*/
#ifndef __FAST_ALLOC_H__
#define __FAST_ALLOC_H__
#include <stddef.h>
// Fast structure allocator. Designed for small objects that are
// frequently allocated and deallocated. This code is derived from the
// 'alloc_struct' package used in WWT and Blizzard. C++ provides a
// much nicer framework for the same optimization. The package is
// implemented as a class, FastAlloc. Allocation and deletion are
// performed using FastAlloc's new and delete operators. Any object
// that derives from the FastAlloc class will transparently use this
// allocation package.
// The static allocate() and deallocate() methods can also be called
// directly if desired.
// In order for derived classes to call delete with the correct
// structure size even when they are deallocated via a base-type
// pointer, they must have a virtual destructor. It is sufficient for
// FastAlloc to declare a virtual destructor (as it does); it is not
// required for derived classes to declare their own destructor. The
// compiler will automatically generate a virtual destructor for each
// derived class. However, it is more efficient if each derived class
// defines an inline destructor, so that the compiler can statically
// collapse the destructor call chain back up the inheritance
// hierarchy.
// Uncomment this #define to track in-use objects
// (for debugging memory leaks).
//#define FAST_ALLOC_DEBUG
// Uncomment this #define to count news, deletes, and chunk allocations
// (by bucket).
// #define FAST_ALLOC_STATS
#include "config/no_fast_alloc.hh"
#if NO_FAST_ALLOC
class FastAlloc {
};
#else
class FastAlloc {
public:
static void *allocate(size_t);
static void deallocate(void *, size_t);
void *operator new(size_t);
void operator delete(void *, size_t);
#ifdef FAST_ALLOC_DEBUG
FastAlloc();
FastAlloc(FastAlloc*,FastAlloc*); // for inUseHead, see below
virtual ~FastAlloc();
#else
virtual ~FastAlloc() {}
#endif
private:
// Max_Alloc_Size is the largest object that can be allocated with
// this class. There's no fundamental limit, but this limits the
// size of the freeLists array. Let's not make this really huge
// like in Blizzard.
static const int Max_Alloc_Size = 512;
// Alloc_Quantum is the difference in size between adjacent
// buckets in the free list array.
static const int Log2_Alloc_Quantum = 3;
static const int Alloc_Quantum = (1 << Log2_Alloc_Quantum);
// Num_Buckets = bucketFor(Max_Alloc_Size) + 1
static const int Num_Buckets =
((Max_Alloc_Size + Alloc_Quantum - 1) >> Log2_Alloc_Quantum) + 1;
// when we call new() for more structures, how many should we get?
static const int Num_Structs_Per_New = 20;
static int bucketFor(size_t);
static void *moreStructs(int bucket);
static void *freeLists[Num_Buckets];
#ifdef FAST_ALLOC_STATS
static unsigned newCount[Num_Buckets];
static unsigned deleteCount[Num_Buckets];
static unsigned allocCount[Num_Buckets];
#endif
#ifdef FAST_ALLOC_DEBUG
// per-object debugging fields
bool inUse; // in-use flag
FastAlloc *inUsePrev; // ptrs to build list of in-use objects
FastAlloc *inUseNext;
// 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);
#endif
};
inline
int FastAlloc::bucketFor(size_t sz)
{
return (sz + Alloc_Quantum - 1) >> Log2_Alloc_Quantum;
}
inline
void *FastAlloc::allocate(size_t sz)
{
int b;
void *p;
if (sz > Max_Alloc_Size)
return (void *)::new char[sz];
b = bucketFor(sz);
p = freeLists[b];
if (p)
freeLists[b] = *(void **)p;
else
p = moreStructs(b);
#ifdef FAST_ALLOC_STATS
++newCount[b];
#endif
return p;
}
inline
void FastAlloc::deallocate(void *p, size_t sz)
{
int b;
if (sz > Max_Alloc_Size)
{
::delete [] (char *)p;
return;
}
b = bucketFor(sz);
*(void **)p = freeLists[b];
freeLists[b] = p;
#ifdef FAST_ALLOC_STATS
++deleteCount[b];
#endif
}
inline
void *FastAlloc::operator new(size_t sz)
{
return allocate(sz);
}
inline
void FastAlloc::operator delete(void *p, size_t sz)
{
deallocate(p, sz);
}
#endif // NO_FAST_ALLOC
#endif // __FAST_ALLOC_H__