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

View File

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

View File

@ -54,16 +54,12 @@ private:
}; };
template<typename T> template<typename T>
struct Model : public Concept struct Model : public Concept, public UseMemoryDomain<MemoryDomain::Values>
{ {
Model(T&& val) : m_content(std::move(val)) {} Model(T&& val) : m_content(std::move(val)) {}
const std::type_info& type() const override { return typeid(T); } const std::type_info& type() const override { return typeid(T); }
T m_content; 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; std::unique_ptr<Concept> m_value;