22 #include "base/integral_types.h"
85 class Allocatable::Helper {
94 : placement_allocator_(NULL) {}
97 void AddAllocationData(
const void* memory_ptr,
size_t size,
99 const void* end_ptr =
reinterpret_cast<const uint8*
>(memory_ptr) + size;
100 allocations_.push_back(AllocationData(MemoryRange(memory_ptr, end_ptr),
101 allocator, AllocationData::kNew));
105 void AddPlacementAllocationData(
const void* memory_ptr,
size_t size,
107 const void* end_ptr =
reinterpret_cast<const uint8*
>(memory_ptr) + size;
108 allocations_.push_back(AllocationData(MemoryRange(memory_ptr, end_ptr),
110 AllocationData::kPlacement));
114 void AddDeallocationData(
const void *memory_ptr,
Allocator* allocator) {
115 deallocations_.push_back(DeallocationData(memory_ptr, allocator));
123 bool FindAllocationData(
const void* instance_ptr,
Allocator** allocator_out,
124 const void** memory_ptr_out);
129 const AllocatorPtr FindDeallocationData(
const void* memory_ptr);
133 return placement_allocator_;
137 void SetPlacementAllocator(
Allocator* allocator) {
138 placement_allocator_ = allocator;
144 MemoryRange(
const void* min_in,
const void* max_in)
145 : min_address(min_in), max_address(max_in) {}
146 const void* min_address;
147 const void* max_address;
152 struct AllocationData {
153 enum AllocationType {
157 AllocationData(
const MemoryRange& memory_range_in,
Allocator* allocator_in,
158 AllocationType allocation_type_in)
159 : memory_range(memory_range_in),
160 allocator(allocator_in),
161 allocation_type(allocation_type_in) {}
163 MemoryRange memory_range;
169 AllocationType allocation_type;
173 struct DeallocationData {
174 DeallocationData(
const void* memory_ptr_in,
Allocator* allocator_in)
175 : memory_ptr(memory_ptr_in), allocator(allocator_in) {}
177 const void* memory_ptr;
189 std::vector<AllocationData> allocations_;
190 std::vector<DeallocationData> deallocations_;
194 bool Allocatable::Helper::FindAllocationData(
const void* instance_ptr,
196 const void** memory_ptr_out) {
197 const size_t num_allocations = allocations_.size();
198 for (
size_t i = 0; i < num_allocations; ++i) {
199 AllocationData& ad = allocations_[i];
200 const void* memory_start = ad.memory_range.min_address;
201 const void* memory_end = ad.memory_range.max_address;
202 if (memory_start <= instance_ptr && instance_ptr < memory_end) {
203 *allocator_out = ad.allocator;
208 ad.allocation_type == AllocationData::kNew ? memory_start : NULL;
209 *memory_ptr_out = memory_start;
211 allocations_.erase(allocations_.begin() + i);
217 if (placement_allocator_) {
218 *allocator_out = placement_allocator_;
219 *memory_ptr_out = NULL;
226 const AllocatorPtr Allocatable::Helper::FindDeallocationData(
227 const void* memory_ptr) {
229 const size_t num_deallocations = deallocations_.size();
231 for (
size_t i = 0; i < num_deallocations; ++i) {
232 DeallocationData& dd = deallocations_[i];
233 if (dd.memory_ptr == memory_ptr) {
234 allocator = dd.allocator;
235 deallocations_.erase(deallocations_.begin() + i);
261 void Allocatable::Construct() {
265 const void* memory_ptr;
266 if (GetHelper()->FindAllocationData(
this, &allocator, &memory_ptr)) {
267 allocator_.
Reset(allocator);
268 memory_ptr_ = memory_ptr;
275 :
allocator_(allocator_in), memory_ptr_(NULL) {
277 const void* memory_ptr;
282 DCHECK(!GetHelper()->FindAllocationData(
this, &allocator, &memory_ptr))
283 <<
"Allocatable can take an AllocatorPtr in its constructor only when "
284 "created on the stack";
291 GetHelper()->AddDeallocationData(memory_ptr_, allocator_.
Get());
294 void* Allocatable::New(
size_t size,
const AllocatorPtr& allocator) {
297 void* memory_ptr = a->AllocateMemory(size);
301 GetHelper()->AddAllocationData(memory_ptr, size, a.
Get());
306 void Allocatable::Delete(
void* memory_ptr) {
310 AllocatorPtr allocator = GetHelper()->FindDeallocationData(memory_ptr);
312 allocator->DeallocateMemory(memory_ptr);
316 void* Allocatable::PlacementNew(
size_t size,
const AllocatorPtr& allocator,
319 GetHelper()->AddPlacementAllocationData(memory_ptr, size, allocator.Get());
323 Allocator* Allocatable::GetPlacementAllocator() {
324 return GetHelper()->GetPlacementAllocator();
327 void Allocatable::SetPlacementAllocator(Allocator* allocator) {
328 GetHelper()->SetPlacementAllocator(allocator);
331 Allocatable::Helper* Allocatable::GetHelper() {
335 return s_helper->Get();
#define ION_DECLARE_SAFE_STATIC_POINTER(type, variable)
Declare a static non-array pointer and calls a default constructor.
base::AllocatorPtr allocator_
The Allocator for the FreeTypeManager and all its Fonts.
virtual ~Allocatable()
The destructor clears the reference to the allocator.
SharedPtr< Allocator > AllocatorPtr
T * Get() const
Returns a raw pointer to the instance, which may be NULL.
static const AllocatorPtr & GetNonNullAllocator(const AllocatorPtr &allocator)
This convenience function can be used where a non-NULL Allocator pointer is needed.
Allocatable is an abstract base class for classes whose memory is managed by an Allocator.
Allocatable()
This constructor sets up the Allocator pointer.
Allocator is an abstract base class for a memory allocator used for Ion objects derived from Allocata...
void Reset(T *new_shared)
Changes the pointer to point to the given shared, which may be NULL.
A SharedPtr is a smart shared pointer to an instance of some class that implements reference counting...