port optimizations for cpp03

This commit is contained in:
Arenoros 2023-09-30 13:10:18 +03:00
parent f2b3f52d44
commit 62de80fa72
4 changed files with 290 additions and 291 deletions

View File

@ -29,121 +29,101 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
class zone { class zone {
struct finalizer { struct finalizer {
finalizer(void (*func)(void*), void* data):m_func(func), m_data(data) {} finalizer(void (*func)(void*), void* data, finalizer* next): m_func(func), m_data(data), m_next(next) {}
void operator()() { m_func(m_data); } void operator()() { m_func(m_data); }
void (*m_func)(void*); void (*m_func)(void*);
void* m_data; void* m_data;
finalizer* m_next;
}; };
struct finalizer_array { struct finalizer_array {
finalizer_array():m_tail(MSGPACK_NULLPTR), m_end(MSGPACK_NULLPTR), m_array(MSGPACK_NULLPTR) {} finalizer_array(): m_head(MSGPACK_NULLPTR) {}
void call() {
finalizer* fin = m_tail;
for(; fin != m_array; --fin) (*(fin-1))();
}
~finalizer_array() { ~finalizer_array() {
call(); clear();
::free(m_array);
} }
void clear() { void clear() {
call(); finalizer* fin = m_head;
m_tail = m_array; finalizer* tmp = nullptr;
while(fin) {
(*fin)();
tmp = fin;
fin = fin->m_next;
delete tmp;
} }
void push(void (*func)(void* data), void* data) m_head = MSGPACK_NULLPTR;
{
finalizer* fin = m_tail;
if(fin == m_end) {
push_expand(func, data);
return;
} }
fin->m_func = func; void push(void (*func)(void* data), void* data) {
fin->m_data = data; m_head = new finalizer(func, data, m_head);
}
++m_tail; void pop() {
auto n = m_head->m_next;
delete m_head;
m_head = n;
} }
void push_expand(void (*func)(void*), void* data) {
const size_t nused = static_cast<size_t>(m_end - m_array);
size_t nnext;
if(nused == 0) {
nnext = (sizeof(finalizer) < 72/2) ?
72 / sizeof(finalizer) : 8;
} else {
nnext = nused * 2;
}
finalizer* tmp =
static_cast<finalizer*>(::realloc(m_array, sizeof(finalizer) * nnext));
if(!tmp) {
throw std::bad_alloc();
}
m_array = tmp;
m_end = tmp + nnext;
m_tail = tmp + nused;
new (m_tail) finalizer(func, data);
++m_tail; finalizer* m_head;
} private:
finalizer* m_tail; finalizer_array(const finalizer_array&);
finalizer* m_end; finalizer_array& operator=(const finalizer_array&);
finalizer* m_array;
}; };
struct chunk { struct chunk {
chunk* m_next; chunk* m_next;
}; };
struct chunk_list {
chunk_list(size_t chunk_size)
{
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
if(!c) {
throw std::bad_alloc();
}
m_head = c; struct chunk_list {
m_free = chunk_size; chunk_list(size_t chunk_size, char* ptr): m_free(chunk_size), m_ptr(ptr), m_head(MSGPACK_NULLPTR) {}
m_ptr = reinterpret_cast<char*>(c) + sizeof(chunk); ~chunk_list() {
c->m_next = MSGPACK_NULLPTR;
}
~chunk_list()
{
chunk* c = m_head; chunk* c = m_head;
while(c) { while(c) {
chunk* n = c->m_next; chunk* n = c->m_next;
::free(c); ::free(c);
c = n; c = n;
} }
m_head = MSGPACK_NULLPTR;
} }
void clear(size_t chunk_size)
{ void clear(size_t chunk_size, char* ptr) {
chunk* c = m_head; chunk* c = m_head;
while(true) { while(c) {
chunk* n = c->m_next; chunk* n = c->m_next;
if(n) {
::free(c); ::free(c);
c = n; c = n;
} else {
m_head = c;
break;
} }
} m_head = MSGPACK_NULLPTR;
m_head->m_next = MSGPACK_NULLPTR;
m_free = chunk_size; m_free = chunk_size;
m_ptr = reinterpret_cast<char*>(m_head) + sizeof(chunk); m_ptr = ptr;
} }
size_t m_free; size_t m_free;
char* m_ptr; char* m_ptr;
chunk* m_head; chunk* m_head;
private:
chunk_list(const chunk_list&);
chunk_list& operator=(const chunk_list&);
}; };
size_t m_chunk_size; size_t m_chunk_size;
chunk_list m_chunk_list; chunk_list* m_chunk_list;
finalizer_array m_finalizer_array; finalizer_array m_finalizer_array;
public: public:
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE); zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE);
~zone();
public:
void* allocate_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN); void* allocate_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN);
void* allocate_no_align(size_t size); void* allocate_no_align(size_t size);
bool allocated() {
return m_chunk_list != MSGPACK_NULLPTR;
}
void push_finalizer(void (*func)(void*), void* data); void push_finalizer(void (*func)(void*), void* data);
template <typename T> template <typename T>
@ -152,24 +132,23 @@ public:
void clear(); void clear();
void swap(zone& o); void swap(zone& o);
static void* operator new(std::size_t size)
{ static void* operator new(std::size_t size) {
void* p = ::malloc(size); void* p = ::malloc(size);
if (!p) throw std::bad_alloc(); if (!p) throw std::bad_alloc();
return p; return p;
} }
static void operator delete(void *p) /* throw() */
{ static void operator delete(void *p) /* throw() */ {
::free(p); ::free(p);
} }
static void* operator new(std::size_t size, void* place) /* throw() */
{ static void* operator new(std::size_t /*size*/, void* mem) /* throw() */ {
return ::operator new(size, place); return mem;
}
static void operator delete(void* p, void* place) /* throw() */
{
::operator delete(p, place);
} }
static void operator delete(void * /*p*/, void* /*mem*/) /* throw() */ {}
/// @cond /// @cond
<%0.upto(GENERATION_LIMIT) {|i|%> <%0.upto(GENERATION_LIMIT) {|i|%>
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>> template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
@ -188,18 +167,26 @@ private:
static char* get_aligned(char* ptr, size_t align); static char* get_aligned(char* ptr, size_t align);
chunk_list& get_chank_lst();
char* allocate_expand(size_t size); char* allocate_expand(size_t size);
private: private:
zone(const zone&); zone(const zone&);
zone& operator=(const zone&); zone& operator=(const zone&);
}; };
inline zone::zone(size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(m_chunk_size) inline zone::zone(size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(MSGPACK_NULLPTR) {}
{
inline zone::~zone() {
m_finalizer_array.~finalizer_array();
if(m_chunk_list) {
m_chunk_list->~chunk_list();
::free(m_chunk_list);
m_chunk_list = MSGPACK_NULLPTR;
}
} }
inline char* zone::get_aligned(char* ptr, size_t align) inline char* zone::get_aligned(char* ptr, size_t align) {
{
MSGPACK_ASSERT(align != 0 && (align & (align - 1)) == 0); // align must be 2^n (n >= 0) MSGPACK_ASSERT(align != 0 && (align & (align - 1)) == 0); // align must be 2^n (n >= 0)
return return
reinterpret_cast<char*>( reinterpret_cast<char*>(
@ -207,37 +194,45 @@ inline char* zone::get_aligned(char* ptr, size_t align)
); );
} }
inline void* zone::allocate_align(size_t size, size_t align) inline zone::chunk_list& zone::get_chank_lst() {
{ if (!m_chunk_list) {
char* aligned = get_aligned(m_chunk_list.m_ptr, align); auto ptr = ::malloc(sizeof(chunk_list) + m_chunk_size);
size_t adjusted_size = size + static_cast<size_t>(aligned - m_chunk_list.m_ptr); if (!ptr)
if (m_chunk_list.m_free < adjusted_size) { throw std::bad_alloc();
m_chunk_list = new (ptr) chunk_list(m_chunk_size, reinterpret_cast<char*>(ptr) + sizeof(chunk_list));
}
return *m_chunk_list;
}
inline void* zone::allocate_align(size_t size, size_t align) {
chunk_list& chank_lst = get_chank_lst();
char* aligned = get_aligned(chank_lst.m_ptr, align);
size_t adjusted_size = size + static_cast<size_t>(aligned - chank_lst.m_ptr);
if (chank_lst.m_free < adjusted_size) {
size_t enough_size = size + align - 1; size_t enough_size = size + align - 1;
char* ptr = allocate_expand(enough_size); char* ptr = allocate_expand(enough_size);
aligned = get_aligned(ptr, align); aligned = get_aligned(ptr, align);
adjusted_size = size + static_cast<size_t>(aligned - m_chunk_list.m_ptr); adjusted_size = size + static_cast<size_t>(aligned - chank_lst.m_ptr);
} }
m_chunk_list.m_free -= adjusted_size; chank_lst.m_free -= adjusted_size;
m_chunk_list.m_ptr += adjusted_size; chank_lst.m_ptr += adjusted_size;
return aligned; return aligned;
} }
inline void* zone::allocate_no_align(size_t size) inline void* zone::allocate_no_align(size_t size) {
{ chunk_list& chank_lst = get_chank_lst();
char* ptr = m_chunk_list.m_ptr; char* ptr = chank_lst.m_ptr;
if(m_chunk_list.m_free < size) { if(chank_lst.m_free < size) {
ptr = allocate_expand(size); ptr = allocate_expand(size);
} }
m_chunk_list.m_free -= size; chank_lst.m_free -= size;
m_chunk_list.m_ptr += size; chank_lst.m_ptr += size;
return ptr; return ptr;
} }
inline char* zone::allocate_expand(size_t size) inline char* zone::allocate_expand(size_t size) {
{ chunk_list& cl = get_chank_lst();
chunk_list* const cl = &m_chunk_list;
size_t sz = m_chunk_size; size_t sz = m_chunk_size;
while(sz < size) { while(sz < size) {
@ -254,33 +249,31 @@ inline char* zone::allocate_expand(size_t size)
char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk); char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
c->m_next = cl->m_head; c->m_next = cl.m_head;
cl->m_head = c; cl.m_head = c;
cl->m_free = sz; cl.m_free = sz;
cl->m_ptr = ptr; cl.m_ptr = ptr;
return ptr; return ptr;
} }
inline void zone::push_finalizer(void (*func)(void*), void* data) inline void zone::push_finalizer(void (*func)(void*), void* data) {
{
m_finalizer_array.push(func, data); m_finalizer_array.push(func, data);
} }
template <typename T> template <typename T>
inline void zone::push_finalizer(msgpack::unique_ptr<T> obj) inline void zone::push_finalizer(msgpack::unique_ptr<T> obj) {
{
m_finalizer_array.push(&zone::object_delete<T>, obj.release()); m_finalizer_array.push(&zone::object_delete<T>, obj.release());
} }
inline void zone::clear() inline void zone::clear() {
{
m_finalizer_array.clear(); m_finalizer_array.clear();
m_chunk_list.clear(m_chunk_size); if (m_chunk_list) {
m_chunk_list->clear(m_chunk_size, reinterpret_cast<char*>(m_chunk_list) + sizeof(chunk_list));
}
} }
inline void zone::swap(zone& o) inline void zone::swap(zone& o) {
{
using std::swap; using std::swap;
swap(m_chunk_size, o.m_chunk_size); swap(m_chunk_size, o.m_chunk_size);
swap(m_chunk_list, o.m_chunk_list); swap(m_chunk_list, o.m_chunk_list);
@ -288,26 +281,22 @@ inline void zone::swap(zone& o)
} }
template <typename T> template <typename T>
void zone::object_destruct(void* obj) void zone::object_delete(void* obj) {
{
static_cast<T*>(obj)->~T();
}
template <typename T>
void zone::object_delete(void* obj)
{
delete static_cast<T*>(obj); delete static_cast<T*>(obj);
} }
inline void zone::undo_allocate(size_t size) template <typename T>
{ void zone::object_destruct(void* obj) {
m_chunk_list.m_ptr -= size; static_cast<T*>(obj)->~T();
m_chunk_list.m_free += size;
} }
inline std::size_t aligned_size( inline void zone::undo_allocate(size_t size) {
std::size_t size, chunk_list& cl = get_chank_lst();
std::size_t align) { cl.m_ptr -= size;
cl.m_free += size;
}
inline std::size_t aligned_size(std::size_t size, std::size_t align) {
return (size + align - 1) / align * align; return (size + align - 1) / align * align;
} }
@ -326,7 +315,7 @@ T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>)
try { try {
return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>); return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }

View File

@ -29,121 +29,101 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
class zone { class zone {
struct finalizer { struct finalizer {
finalizer(void (*func)(void*), void* data):m_func(func), m_data(data) {} finalizer(void (*func)(void*), void* data, finalizer* next): m_func(func), m_data(data), m_next(next) {}
void operator()() { m_func(m_data); } void operator()() { m_func(m_data); }
void (*m_func)(void*); void (*m_func)(void*);
void* m_data; void* m_data;
finalizer* m_next;
}; };
struct finalizer_array { struct finalizer_array {
finalizer_array():m_tail(MSGPACK_NULLPTR), m_end(MSGPACK_NULLPTR), m_array(MSGPACK_NULLPTR) {} finalizer_array(): m_head(MSGPACK_NULLPTR) {}
void call() {
finalizer* fin = m_tail;
for(; fin != m_array; --fin) (*(fin-1))();
}
~finalizer_array() { ~finalizer_array() {
call(); clear();
::free(m_array);
} }
void clear() { void clear() {
call(); finalizer* fin = m_head;
m_tail = m_array; finalizer* tmp = nullptr;
while(fin) {
(*fin)();
tmp = fin;
fin = fin->m_next;
delete tmp;
} }
void push(void (*func)(void* data), void* data) m_head = MSGPACK_NULLPTR;
{
finalizer* fin = m_tail;
if(fin == m_end) {
push_expand(func, data);
return;
} }
fin->m_func = func; void push(void (*func)(void* data), void* data) {
fin->m_data = data; m_head = new finalizer(func, data, m_head);
}
++m_tail; void pop() {
auto n = m_head->m_next;
delete m_head;
m_head = n;
} }
void push_expand(void (*func)(void*), void* data) {
const size_t nused = static_cast<size_t>(m_end - m_array);
size_t nnext;
if(nused == 0) {
nnext = (sizeof(finalizer) < 72/2) ?
72 / sizeof(finalizer) : 8;
} else {
nnext = nused * 2;
}
finalizer* tmp =
static_cast<finalizer*>(::realloc(m_array, sizeof(finalizer) * nnext));
if(!tmp) {
throw std::bad_alloc();
}
m_array = tmp;
m_end = tmp + nnext;
m_tail = tmp + nused;
new (m_tail) finalizer(func, data);
++m_tail; finalizer* m_head;
} private:
finalizer* m_tail; finalizer_array(const finalizer_array&);
finalizer* m_end; finalizer_array& operator=(const finalizer_array&);
finalizer* m_array;
}; };
struct chunk { struct chunk {
chunk* m_next; chunk* m_next;
}; };
struct chunk_list {
chunk_list(size_t chunk_size)
{
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
if(!c) {
throw std::bad_alloc();
}
m_head = c; struct chunk_list {
m_free = chunk_size; chunk_list(size_t chunk_size, char* ptr): m_free(chunk_size), m_ptr(ptr), m_head(MSGPACK_NULLPTR) {}
m_ptr = reinterpret_cast<char*>(c) + sizeof(chunk); ~chunk_list() {
c->m_next = MSGPACK_NULLPTR;
}
~chunk_list()
{
chunk* c = m_head; chunk* c = m_head;
while(c) { while(c) {
chunk* n = c->m_next; chunk* n = c->m_next;
::free(c); ::free(c);
c = n; c = n;
} }
m_head = MSGPACK_NULLPTR;
} }
void clear(size_t chunk_size)
{ void clear(size_t chunk_size, char* ptr) {
chunk* c = m_head; chunk* c = m_head;
while(true) { while(c) {
chunk* n = c->m_next; chunk* n = c->m_next;
if(n) {
::free(c); ::free(c);
c = n; c = n;
} else {
m_head = c;
break;
} }
} m_head = MSGPACK_NULLPTR;
m_head->m_next = MSGPACK_NULLPTR;
m_free = chunk_size; m_free = chunk_size;
m_ptr = reinterpret_cast<char*>(m_head) + sizeof(chunk); m_ptr = ptr;
} }
size_t m_free; size_t m_free;
char* m_ptr; char* m_ptr;
chunk* m_head; chunk* m_head;
private:
chunk_list(const chunk_list&);
chunk_list& operator=(const chunk_list&);
}; };
size_t m_chunk_size; size_t m_chunk_size;
chunk_list m_chunk_list; chunk_list* m_chunk_list;
finalizer_array m_finalizer_array; finalizer_array m_finalizer_array;
public: public:
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE); zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE);
~zone();
public:
void* allocate_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN); void* allocate_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN);
void* allocate_no_align(size_t size); void* allocate_no_align(size_t size);
bool allocated() {
return m_chunk_list != MSGPACK_NULLPTR;
}
void push_finalizer(void (*func)(void*), void* data); void push_finalizer(void (*func)(void*), void* data);
template <typename T> template <typename T>
@ -152,24 +132,23 @@ public:
void clear(); void clear();
void swap(zone& o); void swap(zone& o);
static void* operator new(std::size_t size)
{ static void* operator new(std::size_t size) {
void* p = ::malloc(size); void* p = ::malloc(size);
if (!p) throw std::bad_alloc(); if (!p) throw std::bad_alloc();
return p; return p;
} }
static void operator delete(void *p) /* throw() */
{ static void operator delete(void *p) /* throw() */ {
::free(p); ::free(p);
} }
static void* operator new(std::size_t size, void* place) /* throw() */
{ static void* operator new(std::size_t /*size*/, void* mem) /* throw() */ {
return ::operator new(size, place); return mem;
}
static void operator delete(void* p, void* place) /* throw() */
{
::operator delete(p, place);
} }
static void operator delete(void * /*p*/, void* /*mem*/) /* throw() */ {}
/// @cond /// @cond
template <typename T> template <typename T>
@ -233,18 +212,26 @@ private:
static char* get_aligned(char* ptr, size_t align); static char* get_aligned(char* ptr, size_t align);
chunk_list& get_chank_lst();
char* allocate_expand(size_t size); char* allocate_expand(size_t size);
private: private:
zone(const zone&); zone(const zone&);
zone& operator=(const zone&); zone& operator=(const zone&);
}; };
inline zone::zone(size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(m_chunk_size) inline zone::zone(size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(MSGPACK_NULLPTR) {}
{
inline zone::~zone() {
m_finalizer_array.~finalizer_array();
if(m_chunk_list) {
m_chunk_list->~chunk_list();
::free(m_chunk_list);
m_chunk_list = MSGPACK_NULLPTR;
}
} }
inline char* zone::get_aligned(char* ptr, size_t align) inline char* zone::get_aligned(char* ptr, size_t align) {
{
MSGPACK_ASSERT(align != 0 && (align & (align - 1)) == 0); // align must be 2^n (n >= 0) MSGPACK_ASSERT(align != 0 && (align & (align - 1)) == 0); // align must be 2^n (n >= 0)
return return
reinterpret_cast<char*>( reinterpret_cast<char*>(
@ -252,37 +239,45 @@ inline char* zone::get_aligned(char* ptr, size_t align)
); );
} }
inline void* zone::allocate_align(size_t size, size_t align) inline zone::chunk_list& zone::get_chank_lst() {
{ if (!m_chunk_list) {
char* aligned = get_aligned(m_chunk_list.m_ptr, align); auto ptr = ::malloc(sizeof(chunk_list) + m_chunk_size);
size_t adjusted_size = size + static_cast<size_t>(aligned - m_chunk_list.m_ptr); if (!ptr)
if (m_chunk_list.m_free < adjusted_size) { throw std::bad_alloc();
m_chunk_list = new (ptr) chunk_list(m_chunk_size, reinterpret_cast<char*>(ptr) + sizeof(chunk_list));
}
return *m_chunk_list;
}
inline void* zone::allocate_align(size_t size, size_t align) {
chunk_list& chank_lst = get_chank_lst();
char* aligned = get_aligned(chank_lst.m_ptr, align);
size_t adjusted_size = size + static_cast<size_t>(aligned - chank_lst.m_ptr);
if (chank_lst.m_free < adjusted_size) {
size_t enough_size = size + align - 1; size_t enough_size = size + align - 1;
char* ptr = allocate_expand(enough_size); char* ptr = allocate_expand(enough_size);
aligned = get_aligned(ptr, align); aligned = get_aligned(ptr, align);
adjusted_size = size + static_cast<size_t>(aligned - m_chunk_list.m_ptr); adjusted_size = size + static_cast<size_t>(aligned - chank_lst.m_ptr);
} }
m_chunk_list.m_free -= adjusted_size; chank_lst.m_free -= adjusted_size;
m_chunk_list.m_ptr += adjusted_size; chank_lst.m_ptr += adjusted_size;
return aligned; return aligned;
} }
inline void* zone::allocate_no_align(size_t size) inline void* zone::allocate_no_align(size_t size) {
{ chunk_list& chank_lst = get_chank_lst();
char* ptr = m_chunk_list.m_ptr; char* ptr = chank_lst.m_ptr;
if(m_chunk_list.m_free < size) { if(chank_lst.m_free < size) {
ptr = allocate_expand(size); ptr = allocate_expand(size);
} }
m_chunk_list.m_free -= size; chank_lst.m_free -= size;
m_chunk_list.m_ptr += size; chank_lst.m_ptr += size;
return ptr; return ptr;
} }
inline char* zone::allocate_expand(size_t size) inline char* zone::allocate_expand(size_t size) {
{ chunk_list& cl = get_chank_lst();
chunk_list* const cl = &m_chunk_list;
size_t sz = m_chunk_size; size_t sz = m_chunk_size;
while(sz < size) { while(sz < size) {
@ -299,33 +294,31 @@ inline char* zone::allocate_expand(size_t size)
char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk); char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
c->m_next = cl->m_head; c->m_next = cl.m_head;
cl->m_head = c; cl.m_head = c;
cl->m_free = sz; cl.m_free = sz;
cl->m_ptr = ptr; cl.m_ptr = ptr;
return ptr; return ptr;
} }
inline void zone::push_finalizer(void (*func)(void*), void* data) inline void zone::push_finalizer(void (*func)(void*), void* data) {
{
m_finalizer_array.push(func, data); m_finalizer_array.push(func, data);
} }
template <typename T> template <typename T>
inline void zone::push_finalizer(msgpack::unique_ptr<T> obj) inline void zone::push_finalizer(msgpack::unique_ptr<T> obj) {
{
m_finalizer_array.push(&zone::object_delete<T>, obj.release()); m_finalizer_array.push(&zone::object_delete<T>, obj.release());
} }
inline void zone::clear() inline void zone::clear() {
{
m_finalizer_array.clear(); m_finalizer_array.clear();
m_chunk_list.clear(m_chunk_size); if (m_chunk_list) {
m_chunk_list->clear(m_chunk_size, reinterpret_cast<char*>(m_chunk_list) + sizeof(chunk_list));
}
} }
inline void zone::swap(zone& o) inline void zone::swap(zone& o) {
{
using std::swap; using std::swap;
swap(m_chunk_size, o.m_chunk_size); swap(m_chunk_size, o.m_chunk_size);
swap(m_chunk_list, o.m_chunk_list); swap(m_chunk_list, o.m_chunk_list);
@ -333,26 +326,22 @@ inline void zone::swap(zone& o)
} }
template <typename T> template <typename T>
void zone::object_destruct(void* obj) void zone::object_delete(void* obj) {
{
static_cast<T*>(obj)->~T();
}
template <typename T>
void zone::object_delete(void* obj)
{
delete static_cast<T*>(obj); delete static_cast<T*>(obj);
} }
inline void zone::undo_allocate(size_t size) template <typename T>
{ void zone::object_destruct(void* obj) {
m_chunk_list.m_ptr -= size; static_cast<T*>(obj)->~T();
m_chunk_list.m_free += size;
} }
inline std::size_t aligned_size( inline void zone::undo_allocate(size_t size) {
std::size_t size, chunk_list& cl = get_chank_lst();
std::size_t align) { cl.m_ptr -= size;
cl.m_free += size;
}
inline std::size_t aligned_size(std::size_t size, std::size_t align) {
return (size + align - 1) / align * align; return (size + align - 1) / align * align;
} }
@ -371,7 +360,7 @@ T* zone::allocate()
try { try {
return new (x) T(); return new (x) T();
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -390,7 +379,7 @@ T* zone::allocate(A1 a1)
try { try {
return new (x) T(a1); return new (x) T(a1);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -409,7 +398,7 @@ T* zone::allocate(A1 a1, A2 a2)
try { try {
return new (x) T(a1, a2); return new (x) T(a1, a2);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -428,7 +417,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3)
try { try {
return new (x) T(a1, a2, a3); return new (x) T(a1, a2, a3);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -447,7 +436,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4)
try { try {
return new (x) T(a1, a2, a3, a4); return new (x) T(a1, a2, a3, a4);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -466,7 +455,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
try { try {
return new (x) T(a1, a2, a3, a4, a5); return new (x) T(a1, a2, a3, a4, a5);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -485,7 +474,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
try { try {
return new (x) T(a1, a2, a3, a4, a5, a6); return new (x) T(a1, a2, a3, a4, a5, a6);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -504,7 +493,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
try { try {
return new (x) T(a1, a2, a3, a4, a5, a6, a7); return new (x) T(a1, a2, a3, a4, a5, a6, a7);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -523,7 +512,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
try { try {
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8); return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -542,7 +531,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
try { try {
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9); return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -561,7 +550,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
try { try {
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -580,7 +569,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
try { try {
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -599,7 +588,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
try { try {
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -618,7 +607,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
try { try {
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -637,7 +626,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
try { try {
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }
@ -656,7 +645,7 @@ T* zone::allocate(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
try { try {
return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); return new (x) T(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15);
} catch (...) { } catch (...) {
--m_finalizer_array.m_tail; m_finalizer_array.pop();
undo_allocate(sizeof(T)); undo_allocate(sizeof(T));
throw; throw;
} }

View File

@ -35,6 +35,7 @@ private:
void* m_data; void* m_data;
finalizer* m_next; finalizer* m_next;
}; };
struct finalizer_array { struct finalizer_array {
finalizer_array(): m_head(MSGPACK_NULLPTR) {} finalizer_array(): m_head(MSGPACK_NULLPTR) {}
@ -127,10 +128,14 @@ public:
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE); zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE);
~zone(); ~zone();
public:
void* allocate_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN); void* allocate_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN);
void* allocate_no_align(size_t size); void* allocate_no_align(size_t size);
bool allocated() {
return m_chunk_list != MSGPACK_NULLPTR;
}
void push_finalizer(void (*func)(void*), void* data); void push_finalizer(void (*func)(void*), void* data);
template <typename T> template <typename T>
@ -298,6 +303,9 @@ inline void zone::undo_allocate(size_t size) {
cl.m_free += size; cl.m_free += size;
} }
inline std::size_t aligned_size(std::size_t size, std::size_t align) {
return (size + align - 1) / align * align;
}
template <typename T, typename... Args> template <typename T, typename... Args>
T* zone::allocate(Args... args) { T* zone::allocate(Args... args) {
@ -317,10 +325,6 @@ T* zone::allocate(Args... args) {
} }
} }
inline std::size_t aligned_size(std::size_t size, std::size_t align) {
return (size + align - 1) / align * align;
}
/// @cond /// @cond
} // MSGPACK_API_VERSION_NAMESPACE(v1) } // MSGPACK_API_VERSION_NAMESPACE(v1)
/// @endcond /// @endcond

17
process.rb Normal file
View File

@ -0,0 +1,17 @@
require 'erb'
files = {
"erb/v1/cpp03_msgpack_tuple_decl.hpp" => "include/msgpack/v1/adaptor/detail/cpp03_msgpack_tuple_decl.hpp",
"erb/v1/cpp03_msgpack_tuple.hpp" => "include/msgpack/v1/adaptor/detail/cpp03_msgpack_tuple.hpp",
"erb/v1/cpp03_define_array_decl.hpp" => "include/msgpack/v1/adaptor/detail/cpp03_define_array_decl.hpp",
"erb/v1/cpp03_define_array.hpp" => "include/msgpack/v1/adaptor/detail/cpp03_define_array.hpp",
"erb/v1/cpp03_define_map_decl.hpp" => "include/msgpack/v1/adaptor/detail/cpp03_define_map_decl.hpp",
"erb/v1/cpp03_define_map.hpp" => "include/msgpack/v1/adaptor/detail/cpp03_define_map.hpp",
"erb/v1/cpp03_zone_decl.hpp" => "include/msgpack/v1/detail/cpp03_zone_decl.hpp",
"erb/v1/cpp03_zone.hpp" => "include/msgpack/v1/detail/cpp03_zone.hpp"
}
files.map { |erb, hpp|
res = ERB.new(File.open(erb+".erb").read).result
File.write(hpp, res)
}