source: proiecte/swift/trunk/lib/hoard-371/src/heaplayers/sanitycheckheap.h @ 176

Last change on this file since 176 was 176, checked in by (none), 14 years ago
  • imported repo from "guagal"
File size: 3.0 KB
Line 
1/* -*- C++ -*- */
2
3#include <map>
4#include "stlallocator.h"
5
6#ifndef _SANITYCHECKHEAP_H_
7#define _SANITYCHECKHEAP_H_
8
9/**
10* @class SanityCheckHeap
11* @brief Checks for memory allocation usage errors at runtime.
12* See the "error messages" for the kinds of errors this layer can catch.
13* @author Emery Berger
14*/
15
16#include "mallocheap.h"
17#include "zoneheap.h"
18#include "stlallocator.h"
19#include "mmapheap.h"
20
21namespace HL {
22
23template <class SuperHeap>
24class SanityCheckHeap : public SuperHeap {
25private:
26
27  /// Define a local allocator that lets us use the SuperHeap for the map.
28  /// This approach lets us use SanityCheckHeaps when we're replacing malloc.
29
30  // The objects are pairs, mapping void * pointers to sizes.
31  typedef std::pair<const void *, int> objType;
32
33  // The heap is a simple freelist heap.
34  typedef HL::FreelistHeap<HL::ZoneHeap<HL::MmapHeap, 16384> > heapType;
35
36  // And we wrap it up so it can be used as an STL allocator.
37  typedef HL::STLAllocator<objType, heapType> localAllocator;
38
39  typedef std::less<void *> localComparator;
40
41  /// A map of pointers to objects and their allocated sizes.
42  typedef std::map<void *, int, localComparator, localAllocator> mapType;
43 
44  /// A freed object has a special size, -1.
45  enum { FREED = -1 };
46 
47  /**
48   * @brief "Error messages", used in asserts.
49   * These must all equal zero.
50   */
51  enum { MALLOC_RETURNED_ALLOCATED_OBJECT = 0,
52         FREE_CALLED_ON_OBJECT_I_NEVER_ALLOCATED = 0,
53         FREE_CALLED_TWICE_ON_SAME_OBJECT = 0 };
54 
55public:
56
57  inline void * malloc (size_t sz) {
58    void * ptr = SuperHeap::malloc (sz);
59    if (ptr == NULL) {
60      return NULL;
61    }
62    // Fill the space with a known value.
63    memset (ptr, 'A', sz);
64    // Record this object as allocated.
65    mapType::iterator i;
66    // Look for this object in the map of allocated objects.
67    i = allocatedObjects.find (ptr);
68    if (i == allocatedObjects.end()) {
69      // We didn't find it (this is good).
70      // Add the tuple (ptr, sz).
71      allocatedObjects.insert (std::pair<void *, int>(ptr, sz));
72    } else {
73      // We found it.
74      // It really should have been freed.
75      if ((*i).second != FREED) {
76        // This object is still in use!
77        assert ( MALLOC_RETURNED_ALLOCATED_OBJECT );
78        return NULL;
79      } else {
80        // This object has been freed. Mark it as allocated.
81        (*i).second = sz;
82      }
83    }
84    return ptr;
85  }
86
87  inline void free (void * ptr) {
88    // Look for this object in the list of allocated objects.
89    mapType::iterator i;
90    i = allocatedObjects.find (ptr);
91    if (i == allocatedObjects.end()) {
92      assert ( FREE_CALLED_ON_OBJECT_I_NEVER_ALLOCATED );
93      return;
94    }
95    // We found the object. It should not have been freed already.
96    if ((*i).second == FREED) {
97      // Oops, this object WAS freed before.
98      assert ( FREE_CALLED_TWICE_ON_SAME_OBJECT );
99      return;
100    }
101    // Fill the space with a known value.
102    memset (ptr, 'F', (*i).second);
103    // Really free the pointer.
104    (*i).second = FREED;
105    SuperHeap::free (ptr);
106  }
107
108private:
109
110  /// A map of tuples: (obj address, size).
111  mapType allocatedObjects;
112};
113
114};
115
116#endif
Note: See TracBrowser for help on using the repository browser.