Skip to content

Commit 2c0040c

Browse files
authored
Merge pull request #1101 from msgpack/revert-1096-Arenoros-zone/optimization_size/delayed_malloc
Revert "Arenoros zone/optimization size/delayed malloc"
2 parents 2987022 + f33c7df commit 2c0040c

File tree

4 files changed

+436
-396
lines changed

4 files changed

+436
-396
lines changed

erb/v1/cpp03_zone.hpp.erb

Lines changed: 133 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -29,101 +29,121 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
2929

3030
class zone {
3131
struct finalizer {
32-
finalizer(void (*func)(void*), void* data, finalizer* next): m_func(func), m_data(data), m_next(next) {}
32+
finalizer(void (*func)(void*), void* data):m_func(func), m_data(data) {}
3333
void operator()() { m_func(m_data); }
3434
void (*m_func)(void*);
3535
void* m_data;
36-
finalizer* m_next;
3736
};
38-
3937
struct finalizer_array {
40-
finalizer_array(): m_head(MSGPACK_NULLPTR) {}
41-
38+
finalizer_array():m_tail(MSGPACK_NULLPTR), m_end(MSGPACK_NULLPTR), m_array(MSGPACK_NULLPTR) {}
39+
void call() {
40+
finalizer* fin = m_tail;
41+
for(; fin != m_array; --fin) (*(fin-1))();
42+
}
4243
~finalizer_array() {
43-
clear();
44+
call();
45+
::free(m_array);
4446
}
45-
4647
void clear() {
47-
finalizer* fin = m_head;
48-
finalizer* tmp = MSGPACK_NULLPTR;
49-
while(fin) {
50-
(*fin)();
51-
tmp = fin;
52-
fin = fin->m_next;
53-
delete tmp;
54-
}
55-
m_head = MSGPACK_NULLPTR;
48+
call();
49+
m_tail = m_array;
5650
}
51+
void push(void (*func)(void* data), void* data)
52+
{
53+
finalizer* fin = m_tail;
5754

58-
void push(void (*func)(void* data), void* data) {
59-
m_head = new finalizer(func, data, m_head);
60-
}
55+
if(fin == m_end) {
56+
push_expand(func, data);
57+
return;
58+
}
59+
60+
fin->m_func = func;
61+
fin->m_data = data;
6162

62-
void pop() {
63-
finalizer* n = m_head->m_next;
64-
delete m_head;
65-
m_head = n;
63+
++m_tail;
6664
}
65+
void push_expand(void (*func)(void*), void* data) {
66+
const size_t nused = static_cast<size_t>(m_end - m_array);
67+
size_t nnext;
68+
if(nused == 0) {
69+
nnext = (sizeof(finalizer) < 72/2) ?
70+
72 / sizeof(finalizer) : 8;
71+
} else {
72+
nnext = nused * 2;
73+
}
74+
finalizer* tmp =
75+
static_cast<finalizer*>(::realloc(m_array, sizeof(finalizer) * nnext));
76+
if(!tmp) {
77+
throw std::bad_alloc();
78+
}
79+
m_array = tmp;
80+
m_end = tmp + nnext;
81+
m_tail = tmp + nused;
82+
new (m_tail) finalizer(func, data);
6783

68-
finalizer* m_head;
69-
private:
70-
finalizer_array(const finalizer_array&);
71-
finalizer_array& operator=(const finalizer_array&);
84+
++m_tail;
85+
}
86+
finalizer* m_tail;
87+
finalizer* m_end;
88+
finalizer* m_array;
7289
};
73-
7490
struct chunk {
7591
chunk* m_next;
7692
};
77-
7893
struct chunk_list {
79-
chunk_list(size_t chunk_size, char* ptr): m_free(chunk_size), m_ptr(ptr), m_head(MSGPACK_NULLPTR) {}
80-
~chunk_list() {
94+
chunk_list(size_t chunk_size)
95+
{
96+
chunk* c = static_cast<chunk*>(::malloc(sizeof(chunk) + chunk_size));
97+
if(!c) {
98+
throw std::bad_alloc();
99+
}
100+
101+
m_head = c;
102+
m_free = chunk_size;
103+
m_ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
104+
c->m_next = MSGPACK_NULLPTR;
105+
}
106+
~chunk_list()
107+
{
81108
chunk* c = m_head;
82109
while(c) {
83110
chunk* n = c->m_next;
84111
::free(c);
85112
c = n;
86113
}
87-
m_head = MSGPACK_NULLPTR;
88114
}
89-
90-
void clear(size_t chunk_size, char* ptr) {
115+
void clear(size_t chunk_size)
116+
{
91117
chunk* c = m_head;
92-
while(c) {
118+
while(true) {
93119
chunk* n = c->m_next;
94-
::free(c);
95-
c = n;
120+
if(n) {
121+
::free(c);
122+
c = n;
123+
} else {
124+
m_head = c;
125+
break;
126+
}
96127
}
97-
m_head = MSGPACK_NULLPTR;
128+
m_head->m_next = MSGPACK_NULLPTR;
98129
m_free = chunk_size;
99-
m_ptr = ptr;
130+
m_ptr = reinterpret_cast<char*>(m_head) + sizeof(chunk);
100131
}
101-
102132
size_t m_free;
103133
char* m_ptr;
104134
chunk* m_head;
105-
106-
private:
107-
chunk_list(const chunk_list&);
108-
chunk_list& operator=(const chunk_list&);
109135
};
110-
111136
size_t m_chunk_size;
112-
chunk_list* m_chunk_list;
137+
chunk_list m_chunk_list;
113138
finalizer_array m_finalizer_array;
114139

115140
public:
116141
zone(size_t chunk_size = MSGPACK_ZONE_CHUNK_SIZE);
117-
~zone();
118142

143+
public:
119144
void* allocate_align(size_t size, size_t align = MSGPACK_ZONE_ALIGN);
120-
121145
void* allocate_no_align(size_t size);
122146

123-
bool allocated() {
124-
return m_chunk_list != MSGPACK_NULLPTR;
125-
}
126-
127147
void push_finalizer(void (*func)(void*), void* data);
128148

129149
template <typename T>
@@ -132,23 +152,24 @@ public:
132152
void clear();
133153

134154
void swap(zone& o);
135-
136-
static void* operator new(std::size_t size) {
155+
static void* operator new(std::size_t size)
156+
{
137157
void* p = ::malloc(size);
138158
if (!p) throw std::bad_alloc();
139159
return p;
140160
}
141-
142-
static void operator delete(void *p) /* throw() */ {
161+
static void operator delete(void *p) /* throw() */
162+
{
143163
::free(p);
144164
}
145-
146-
static void* operator new(std::size_t /*size*/, void* mem) /* throw() */ {
147-
return mem;
165+
static void* operator new(std::size_t size, void* place) /* throw() */
166+
{
167+
return ::operator new(size, place);
168+
}
169+
static void operator delete(void* p, void* place) /* throw() */
170+
{
171+
::operator delete(p, place);
148172
}
149-
150-
static void operator delete(void * /*p*/, void* /*mem*/) /* throw() */ {}
151-
152173
/// @cond
153174
<%0.upto(GENERATION_LIMIT) {|i|%>
154175
template <typename T<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
@@ -167,72 +188,56 @@ private:
167188

168189
static char* get_aligned(char* ptr, size_t align);
169190

170-
chunk_list& get_chank_lst();
171-
172191
char* allocate_expand(size_t size);
173192
private:
174193
zone(const zone&);
175194
zone& operator=(const zone&);
176195
};
177196

178-
inline zone::zone(size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(MSGPACK_NULLPTR) {}
179-
180-
inline zone::~zone() {
181-
m_finalizer_array.~finalizer_array();
182-
if(m_chunk_list) {
183-
m_chunk_list->~chunk_list();
184-
::free(m_chunk_list);
185-
m_chunk_list = MSGPACK_NULLPTR;
186-
}
197+
inline zone::zone(size_t chunk_size):m_chunk_size(chunk_size), m_chunk_list(m_chunk_size)
198+
{
187199
}
188200

189-
inline char* zone::get_aligned(char* ptr, size_t align) {
201+
inline char* zone::get_aligned(char* ptr, size_t align)
202+
{
190203
MSGPACK_ASSERT(align != 0 && (align & (align - 1)) == 0); // align must be 2^n (n >= 0)
191204
return
192205
reinterpret_cast<char*>(
193206
reinterpret_cast<uintptr_t>(ptr + (align - 1)) & ~static_cast<uintptr_t>(align - 1)
194207
);
195208
}
196209

197-
inline zone::chunk_list& zone::get_chank_lst() {
198-
if (!m_chunk_list) {
199-
void* ptr = ::malloc(sizeof(chunk_list) + m_chunk_size);
200-
if (!ptr)
201-
throw std::bad_alloc();
202-
m_chunk_list = new (ptr) chunk_list(m_chunk_size, reinterpret_cast<char*>(ptr) + sizeof(chunk_list));
203-
}
204-
return *m_chunk_list;
205-
}
206-
207-
inline void* zone::allocate_align(size_t size, size_t align) {
208-
chunk_list& chank_lst = get_chank_lst();
209-
char* aligned = get_aligned(chank_lst.m_ptr, align);
210-
size_t adjusted_size = size + static_cast<size_t>(aligned - chank_lst.m_ptr);
211-
if (chank_lst.m_free < adjusted_size) {
210+
inline void* zone::allocate_align(size_t size, size_t align)
211+
{
212+
char* aligned = get_aligned(m_chunk_list.m_ptr, align);
213+
size_t adjusted_size = size + static_cast<size_t>(aligned - m_chunk_list.m_ptr);
214+
if (m_chunk_list.m_free < adjusted_size) {
212215
size_t enough_size = size + align - 1;
213216
char* ptr = allocate_expand(enough_size);
214217
aligned = get_aligned(ptr, align);
215-
adjusted_size = size + static_cast<size_t>(aligned - chank_lst.m_ptr);
218+
adjusted_size = size + static_cast<size_t>(aligned - m_chunk_list.m_ptr);
216219
}
217-
chank_lst.m_free -= adjusted_size;
218-
chank_lst.m_ptr += adjusted_size;
220+
m_chunk_list.m_free -= adjusted_size;
221+
m_chunk_list.m_ptr += adjusted_size;
219222
return aligned;
220223
}
221224

222-
inline void* zone::allocate_no_align(size_t size) {
223-
chunk_list& chank_lst = get_chank_lst();
224-
char* ptr = chank_lst.m_ptr;
225-
if(chank_lst.m_free < size) {
225+
inline void* zone::allocate_no_align(size_t size)
226+
{
227+
char* ptr = m_chunk_list.m_ptr;
228+
if(m_chunk_list.m_free < size) {
226229
ptr = allocate_expand(size);
227230
}
228-
chank_lst.m_free -= size;
229-
chank_lst.m_ptr += size;
231+
m_chunk_list.m_free -= size;
232+
m_chunk_list.m_ptr += size;
230233

231234
return ptr;
232235
}
233236

234-
inline char* zone::allocate_expand(size_t size) {
235-
chunk_list& cl = get_chank_lst();
237+
inline char* zone::allocate_expand(size_t size)
238+
{
239+
chunk_list* const cl = &m_chunk_list;
240+
236241
size_t sz = m_chunk_size;
237242

238243
while(sz < size) {
@@ -249,54 +254,60 @@ inline char* zone::allocate_expand(size_t size) {
249254

250255
char* ptr = reinterpret_cast<char*>(c) + sizeof(chunk);
251256

252-
c->m_next = cl.m_head;
253-
cl.m_head = c;
254-
cl.m_free = sz;
255-
cl.m_ptr = ptr;
257+
c->m_next = cl->m_head;
258+
cl->m_head = c;
259+
cl->m_free = sz;
260+
cl->m_ptr = ptr;
256261

257262
return ptr;
258263
}
259264

260-
inline void zone::push_finalizer(void (*func)(void*), void* data) {
265+
inline void zone::push_finalizer(void (*func)(void*), void* data)
266+
{
261267
m_finalizer_array.push(func, data);
262268
}
263269

264270
template <typename T>
265-
inline void zone::push_finalizer(msgpack::unique_ptr<T> obj) {
271+
inline void zone::push_finalizer(msgpack::unique_ptr<T> obj)
272+
{
266273
m_finalizer_array.push(&zone::object_delete<T>, obj.release());
267274
}
268275

269-
inline void zone::clear() {
276+
inline void zone::clear()
277+
{
270278
m_finalizer_array.clear();
271-
if (m_chunk_list) {
272-
m_chunk_list->clear(m_chunk_size, reinterpret_cast<char*>(m_chunk_list) + sizeof(chunk_list));
273-
}
279+
m_chunk_list.clear(m_chunk_size);
274280
}
275281

276-
inline void zone::swap(zone& o) {
282+
inline void zone::swap(zone& o)
283+
{
277284
using std::swap;
278285
swap(m_chunk_size, o.m_chunk_size);
279286
swap(m_chunk_list, o.m_chunk_list);
280-
swap(m_finalizer_array.m_head, o.m_finalizer_array.m_head);
287+
swap(m_finalizer_array, o.m_finalizer_array);
281288
}
282289

283290
template <typename T>
284-
void zone::object_delete(void* obj) {
285-
delete static_cast<T*>(obj);
291+
void zone::object_destruct(void* obj)
292+
{
293+
static_cast<T*>(obj)->~T();
286294
}
287295

288296
template <typename T>
289-
void zone::object_destruct(void* obj) {
290-
static_cast<T*>(obj)->~T();
297+
void zone::object_delete(void* obj)
298+
{
299+
delete static_cast<T*>(obj);
291300
}
292301

293-
inline void zone::undo_allocate(size_t size) {
294-
chunk_list& cl = get_chank_lst();
295-
cl.m_ptr -= size;
296-
cl.m_free += size;
302+
inline void zone::undo_allocate(size_t size)
303+
{
304+
m_chunk_list.m_ptr -= size;
305+
m_chunk_list.m_free += size;
297306
}
298307

299-
inline std::size_t aligned_size(std::size_t size, std::size_t align) {
308+
inline std::size_t aligned_size(
309+
std::size_t size,
310+
std::size_t align) {
300311
return (size + align - 1) / align * align;
301312
}
302313

@@ -315,7 +326,7 @@ T* zone::allocate(<%=(1..i).map{|j|"A#{j} a#{j}"}.join(', ')%>)
315326
try {
316327
return new (x) T(<%=(1..i).map{|j|"a#{j}"}.join(', ')%>);
317328
} catch (...) {
318-
m_finalizer_array.pop();
329+
--m_finalizer_array.m_tail;
319330
undo_allocate(sizeof(T));
320331
throw;
321332
}

0 commit comments

Comments
 (0)