Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
alloctracker.cc
Go to the documentation of this file.
1 
18 #include "ion/base/alloctracker.h"
19 
20 #include <stdlib.h> // For malloc() and free().
21 
22 #include "ion/base/allocator.h"
24 
25 #if !defined(ION_ALLOC_TRACKER_DEFINED)
26 # error alloctracker.cc requires the --track-allocations build option.
27 #endif
28 
30 
35 
36 
37 namespace {
38 
40 static ion::base::AllocTracker* GetTracker() {
41  return ion::base::AllocTracker::GetMutableInstance();
42 }
43 
47 template <typename T>
48 static T* CreateWithPlacementNew() {
49  void* ptr = malloc(sizeof(T));
50  return new(ptr) T;
51 }
52 
53 } // anonymous namespace
54 
55 namespace ion {
56 namespace base {
57 
59 
64 
65 
66 class AllocTracker::Helper {
67  public:
68  Helper()
69  : internal_allocator_(CreateWithPlacementNew<InternalAllocator>()),
70  size_map_(internal_allocator_) {}
71  ~Helper() {}
72 
75  void AddSize(void* ptr, size_t size) {
76  size_map_[ptr] = size;
77  }
78  size_t FindAndRemoveSize(void* ptr) {
79  size_t bytes = 0;
80  SizeMap::iterator it = size_map_.find(ptr);
81  if (it != size_map_.end()) {
82  bytes = it->second;
83  size_map_.erase(it);
84  }
85  return bytes;
86  }
87 
88  private:
90  class InternalAllocator : public ion::base::Allocator {
91  public:
92  virtual void* Allocate(size_t size) {
96  if (AllocTracker* tracker = GetTracker()) {
97  return tracker->New(size, kInternalAlloc);
98  } else {
99  return malloc(size);
100  }
101  }
102  virtual void Deallocate(void* ptr) {
103  GetTracker()->Delete(ptr, kInternalAlloc);
104  }
105 
106  protected:
107  virtual ~InternalAllocator() {}
108  };
109  typedef ion::base::SharedPtr<InternalAllocator> InternalAllocatorPtr;
110 
113  InternalAllocatorPtr internal_allocator_;
114 
116  typedef ion::base::AllocMap<void*, size_t> SizeMap;
117  SizeMap size_map_;
118 };
119 
121 
126 
127 
128 AllocTracker* AllocTracker::GetMutableInstance() {
131  static AllocTracker* tracker = CreateWithPlacementNew<AllocTracker>();
132  return tracker;
133 }
134 
135 const AllocTracker& AllocTracker::GetInstance() {
136  return *GetMutableInstance();
137 }
138 
139 AllocTracker::AllocTracker() {
143  helper_.reset(CreateWithPlacementNew<Helper>());
144 }
145 
146 AllocTracker::~AllocTracker() {
147 }
148 
149 void AllocTracker::SetBaseline() {
150  baseline_counts_ = all_counts_;
151 }
152 
153 void* AllocTracker::New(std::size_t size, AllocType type) {
154  void* ptr = malloc(size);
155 
157  TypeCounts &all_c = all_counts_.counts[type];
158  TypeCounts &open_c = open_counts_.counts[type];
159  ++all_c.allocs;
160  all_c.bytes += size;
161  ++open_c.allocs;
162  open_c.bytes += size;
163 
166  if (type != kInternalAlloc)
167  helper_->AddSize(ptr, size);
168 
169  return ptr;
170 }
171 
172 void AllocTracker::Delete(void* ptr, AllocType type) {
173  size_t bytes = type == kInternalAlloc ? 0 : helper_->FindAndRemoveSize(ptr);
174 
176  TypeCounts &open_c = open_counts_.counts[type];
177  if (open_c.allocs)
178  --open_c.allocs;
179  if (open_c.bytes >= bytes)
180  open_c.bytes -= bytes;
181 
182  free(ptr);
183 }
184 
185 } // namespace base
186 } // namespace ion
187 
189 
194 
195 
196 using ion::base::AllocTracker;
197 
198 void* operator new(std::size_t size) {
199  return GetTracker()->New(size, AllocTracker::kNonArrayAlloc);
200 }
201 
202 void* operator new[](std::size_t size) {
203  return GetTracker()->New(size, AllocTracker::kArrayAlloc);
204 }
205 
206 void operator delete(void* ptr) {
207  GetTracker()->Delete(ptr, AllocTracker::kNonArrayAlloc);
208 }
209 
210 void operator delete[](void* ptr) {
211  GetTracker()->Delete(ptr, AllocTracker::kArrayAlloc);
212 }
const AllocationTrackerPtr & GetTracker() const
Definition: allocator.h:82
std::string type
Definition: printer.cc:353
Allocator is an abstract base class for a memory allocator used for Ion objects derived from Allocata...
Definition: allocator.h:61