Eneboo - Documentación para desarrolladores
src/hoard/src/heaplayers/sanitycheckheap.h
Ir a la documentación de este archivo.
00001 /* -*- C++ -*- */
00002 
00003 #include <map>
00004 #include "stlallocator.h"
00005 
00006 #ifndef _SANITYCHECKHEAP_H_
00007 #define _SANITYCHECKHEAP_H_
00008 
00016 #include "mallocheap.h"
00017 #include "zoneheap.h"
00018 #include "stlallocator.h"
00019 #include "mmapheap.h"
00020 
00021 namespace HL {
00022 
00023 template <class SuperHeap>
00024 class SanityCheckHeap : public SuperHeap {
00025 private:
00026 
00029 
00030   // The objects are pairs, mapping void * pointers to sizes.
00031   typedef std::pair<const void *, int> objType;
00032 
00033   // The heap is a simple freelist heap.
00034   typedef HL::FreelistHeap<HL::ZoneHeap<HL::MmapHeap, 16384> > heapType;
00035 
00036   // And we wrap it up so it can be used as an STL allocator.
00037   typedef HL::STLAllocator<objType, heapType> localAllocator;
00038 
00039   typedef std::less<void *> localComparator;
00040 
00042   typedef std::map<void *, int, localComparator, localAllocator> mapType;
00043   
00045   enum { FREED = -1 };
00046   
00051   enum { MALLOC_RETURNED_ALLOCATED_OBJECT = 0,
00052          FREE_CALLED_ON_OBJECT_I_NEVER_ALLOCATED = 0,
00053          FREE_CALLED_TWICE_ON_SAME_OBJECT = 0 };
00054   
00055 public:
00056 
00057   inline void * malloc (size_t sz) {
00058     void * ptr = SuperHeap::malloc (sz);
00059     if (ptr == NULL) {
00060       return NULL;
00061     }
00062     // Fill the space with a known value.
00063     memset (ptr, 'A', sz);
00064     // Record this object as allocated.
00065     mapType::iterator i;
00066     // Look for this object in the map of allocated objects.
00067     i = allocatedObjects.find (ptr);
00068     if (i == allocatedObjects.end()) {
00069       // We didn't find it (this is good).
00070       // Add the tuple (ptr, sz).
00071       allocatedObjects.insert (std::pair<void *, int>(ptr, sz));
00072     } else {
00073       // We found it.
00074       // It really should have been freed.
00075       if ((*i).second != FREED) {
00076         // This object is still in use!
00077         assert ( MALLOC_RETURNED_ALLOCATED_OBJECT );
00078         return NULL;
00079       } else {
00080         // This object has been freed. Mark it as allocated.
00081         (*i).second = sz;
00082       }
00083     }
00084     return ptr;
00085   }
00086 
00087   inline void free (void * ptr) {
00088     // Look for this object in the list of allocated objects.
00089     mapType::iterator i;
00090     i = allocatedObjects.find (ptr);
00091     if (i == allocatedObjects.end()) {
00092       assert ( FREE_CALLED_ON_OBJECT_I_NEVER_ALLOCATED );
00093       return;
00094     }
00095     // We found the object. It should not have been freed already.
00096     if ((*i).second == FREED) {
00097       // Oops, this object WAS freed before.
00098       assert ( FREE_CALLED_TWICE_ON_SAME_OBJECT );
00099       return;
00100     }
00101     // Fill the space with a known value.
00102     memset (ptr, 'F', (*i).second);
00103     // Really free the pointer.
00104     (*i).second = FREED;
00105     SuperHeap::free (ptr);
00106   }
00107 
00108 private:
00109 
00111   mapType allocatedObjects;
00112 };
00113 
00114 };
00115 
00116 #endif
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Propiedades Amigas 'defines'