Add helper for overloading operator new/delete

This commit is contained in:
Maxime Coste 2015-01-18 18:49:32 +00:00
parent 9b057896d4
commit 39689f0a18
3 changed files with 34 additions and 12 deletions

View File

@ -2,7 +2,6 @@
#define memory_hh_INCLUDED
#include <cstddef>
#include <cstdlib>
#include <new>
#include <utility>
@ -64,6 +63,17 @@ inline const char* domain_name(MemoryDomain domain)
extern size_t domain_allocated_bytes[(size_t)MemoryDomain::Count];
inline void on_alloc(MemoryDomain domain, size_t size)
{
domain_allocated_bytes[(int)domain] += size;
}
inline void on_dealloc(MemoryDomain domain, size_t size)
{
kak_assert(domain_allocated_bytes[(int)domain] >= size);
domain_allocated_bytes[(int)domain] -= size;
}
template<typename T, MemoryDomain domain>
struct Allocator
{
@ -86,16 +96,15 @@ struct Allocator
T* allocate(size_t n)
{
size_t size = sizeof(T) * n;
domain_allocated_bytes[(int)domain] += size;
return reinterpret_cast<T*>(malloc(size));
on_alloc(domain, size);
return reinterpret_cast<T*>(::operator new(size));
}
void deallocate(T* ptr, size_t n)
{
size_t size = sizeof(T) * n;
kak_assert(domain_allocated_bytes[(int)domain] >= size);
domain_allocated_bytes[(int)domain] -= size;
free(ptr);
on_dealloc(domain, size);
::operator delete(ptr);
}
template<class U, class... Args>
@ -129,6 +138,23 @@ private:
static constexpr MemoryDomain helper(...) { return MemoryDomain::Undefined; }
};
template<MemoryDomain d>
struct UseMemoryDomain
{
static constexpr MemoryDomain domain = d;
static void* operator new(size_t size)
{
on_alloc(domain, size);
return ::operator new(size);
}
static void operator delete(void* ptr, size_t size)
{
on_dealloc(domain, size);
::operator delete(ptr);
}
};
}
#endif // memory_hh_INCLUDED

View File

@ -12,7 +12,7 @@ namespace Kakoune
class SharedString : public StringView
{
public:
struct Storage
struct Storage : UseMemoryDomain<MemoryDomain::SharedString>
{
int refcount = 0;
Vector<char, MemoryDomain::SharedString> content;

View File

@ -54,16 +54,12 @@ private:
};
template<typename T>
struct Model : public Concept
struct Model : public Concept, public UseMemoryDomain<MemoryDomain::Values>
{
Model(T&& val) : m_content(std::move(val)) {}
const std::type_info& type() const override { return typeid(T); }
T m_content;
using Alloc = Allocator<Model<T>, MemoryDomain::Values>;
static void* operator new (std::size_t sz) { return Alloc{}.allocate(1); }
static void operator delete (void* ptr) { Alloc{}.deallocate((Model<T>*)ptr, 1); }
};
std::unique_ptr<Concept> m_value;