diff --git a/cpp/object.hpp b/cpp/object.hpp index b1f53690..959d84ec 100644 --- a/cpp/object.hpp +++ b/cpp/object.hpp @@ -69,28 +69,28 @@ class dynamic_packer; struct object_class { virtual ~object_class() {} - virtual bool isnil() const { return false; } - virtual bool xbool() const { throw cast_error(); } - virtual uint8_t xu8() const { throw cast_error(); } - virtual uint16_t xu16() const { throw cast_error(); } - virtual uint32_t xu32() const { throw cast_error(); } - virtual uint64_t xu64() const { throw cast_error(); } - virtual int8_t xi8() const { throw cast_error(); } - virtual int16_t xi16() const { throw cast_error(); } - virtual int32_t xi32() const { throw cast_error(); } - virtual int64_t xi64() const { throw cast_error(); } - virtual float xfloat() const { throw cast_error(); } - virtual double xdouble() const { throw cast_error(); } - virtual raw xraw() { throw cast_error(); } - virtual array& xarray() { throw cast_error(); } - virtual map& xmap() { throw cast_error(); } - virtual const_raw xraw() const { throw cast_error(); } + virtual bool isnil () const { return false; } + virtual bool xbool () const { throw cast_error(); } + virtual uint8_t xu8 () const { throw cast_error(); } + virtual uint16_t xu16 () const { throw cast_error(); } + virtual uint32_t xu32 () const { throw cast_error(); } + virtual uint64_t xu64 () const { throw cast_error(); } + virtual int8_t xi8 () const { throw cast_error(); } + virtual int16_t xi16 () const { throw cast_error(); } + virtual int32_t xi32 () const { throw cast_error(); } + virtual int64_t xi64 () const { throw cast_error(); } + virtual float xfloat () const { throw cast_error(); } + virtual double xdouble() const { throw cast_error(); } + virtual raw xraw () { throw cast_error(); } + virtual array& xarray () { throw cast_error(); } + virtual map& xmap () { throw cast_error(); } + virtual const_raw xraw () const { throw cast_error(); } virtual const array& xarray() const { throw cast_error(); } - virtual const map& xmap() const { throw cast_error(); } + virtual const map& xmap () const { throw cast_error(); } virtual bool operator== (const object_class* x) const { return false; } - bool operator!= (const object_class* x) const { return !(this->operator==(x)); } virtual bool operator< (const object_class* x) const { throw cast_error(); } virtual bool operator> (const object_class* x) const { throw cast_error(); } + bool operator!= (const object_class* x) const { return !(this->operator==(x)); } virtual void pack(dynamic_packer& p) const = 0; operator bool() const { return xbool(); } // FIXME !isnil(); operator uint8_t() const { return xu8(); } @@ -126,24 +126,24 @@ struct object { object(object_class* v) : val(v) {} //object(object_class& v) : val(&v) {} ~object() {} - bool isnil() const { return val->isnil(); } - bool xbool() const { return val->xbool(); } - uint8_t xu8() const { return val->xu8(); } - uint16_t xu16() const { return val->xu16(); } - uint32_t xu32() const { return val->xu32(); } - uint64_t xu64() const { return val->xu64(); } - int8_t xi8() const { return val->xi8(); } - int16_t xi16() const { return val->xi16(); } - int32_t xi32() const { return val->xi32(); } - int64_t xi64() const { return val->xi64(); } - float xfloat() const { return val->xfloat(); } - double xdouble() const { return val->xdouble(); } - raw xraw() { return val->xraw(); } - array& xarray() { return val->xarray(); } - map& xmap() { return val->xmap(); } - const_raw xraw() const { return const_cast(val)->xraw(); } + bool isnil () const { return val->isnil(); } + bool xbool () const { return val->xbool(); } + uint8_t xu8 () const { return val->xu8(); } + uint16_t xu16 () const { return val->xu16(); } + uint32_t xu32 () const { return val->xu32(); } + uint64_t xu64 () const { return val->xu64(); } + int8_t xi8 () const { return val->xi8(); } + int16_t xi16 () const { return val->xi16(); } + int32_t xi32 () const { return val->xi32(); } + int64_t xi64 () const { return val->xi64(); } + float xfloat () const { return val->xfloat(); } + double xdouble() const { return val->xdouble(); } + raw xraw () { return val->xraw(); } + array& xarray () { return val->xarray(); } + map& xmap () { return val->xmap(); } + const_raw xraw () const { return const_cast(val)->xraw(); } const array& xarray() const { return const_cast(val)->xarray(); } - const map& xmap() const { return const_cast(val)->xmap(); } + const map& xmap () const { return const_cast(val)->xmap(); } bool operator== (object x) const { return val->operator== (x.val); } bool operator!= (object x) const { return val->operator!= (x.val); } bool operator< (object x) const { return val->operator< (x.val); } @@ -163,9 +163,9 @@ struct object { operator raw() { return val->operator raw(); } operator array&() { return val->operator array&(); } operator map&() { return val->operator map&(); } - operator raw() const { return val->operator raw(); } - operator array&() const { return val->operator array&(); } - operator map&() const { return val->operator map&(); } + operator const_raw() const { return val->operator const_raw(); } + operator const array&() const { return val->operator const array&(); } + operator const map&() const { return val->operator const map&(); } const object& inspect(std::ostream& s) const { val->inspect(s); return *this; } private: diff --git a/cpp/unpack.cpp b/cpp/unpack.cpp index a0128bbb..7a0cd786 100644 --- a/cpp/unpack.cpp +++ b/cpp/unpack.cpp @@ -21,6 +21,7 @@ namespace msgpack { + struct unpacker::context { context(zone* z) { @@ -98,11 +99,13 @@ void unpacker::expand_buffer(size_t len) else { next_size = UNPACKER_INITIAL_BUFFER_SIZE; } while(next_size < len + m_used) { next_size *= 2; } - // FIXME realloc? - void* tmp = malloc(next_size); + void* tmp = realloc(m_buffer, next_size); if(!tmp) { throw std::bad_alloc(); } - memcpy(tmp, m_buffer, m_used); - free(m_buffer); + m_buffer = tmp; + //void* tmp = malloc(next_size); + //if(!tmp) { throw std::bad_alloc(); } + //memcpy(tmp, m_buffer, m_used); + //free(m_buffer); m_buffer = tmp; m_free = next_size - m_used; diff --git a/cpp/zone.cpp b/cpp/zone.cpp index 22be7592..ff22fc3e 100644 --- a/cpp/zone.cpp +++ b/cpp/zone.cpp @@ -20,34 +20,33 @@ namespace msgpack { -void* zone::alloc() +// FIXME custom allocator? + +void zone::expand_chunk() { - if(m_pool.size()*ZONE_CHUNK_SIZE <= m_used) { - cell_t* chunk = (cell_t*)malloc(sizeof(cell_t)*ZONE_CHUNK_SIZE); - if(!chunk) { throw std::bad_alloc(); } - try { - m_pool.push_back(chunk); - } catch (...) { - free(chunk); - throw; - } + cell_t* chunk = (cell_t*)malloc(sizeof(cell_t)*ZONE_CHUNK_SIZE); + if(!chunk) { throw std::bad_alloc(); } + try { + m_pool.push_back(chunk); + } catch (...) { + free(chunk); + throw; } - void* data = m_pool[m_used/ZONE_CHUNK_SIZE][m_used%ZONE_CHUNK_SIZE].data; - ++m_used; - return data; } void zone::clear() { if(!m_pool.empty()) { - for(size_t b=0; b < m_used/ZONE_CHUNK_SIZE; ++b) { + size_t base_size = m_used / ZONE_CHUNK_SIZE; + size_t extend_size = m_used % ZONE_CHUNK_SIZE; + for(size_t b=0; b < base_size; ++b) { cell_t* c(m_pool[b]); for(size_t e=0; e < ZONE_CHUNK_SIZE; ++e) { reinterpret_cast(c[e].data)->~object_class(); } } cell_t* c(m_pool.back()); - for(size_t e=0; e < m_used%ZONE_CHUNK_SIZE; ++e) { + for(size_t e=0; e < extend_size; ++e) { reinterpret_cast(c[e].data)->~object_class(); } @@ -60,7 +59,8 @@ void zone::clear() } m_used = 0; - for(user_finalizer_t::reverse_iterator it(m_user_finalizer.rbegin()), it_end(m_user_finalizer.rend()); + for(user_finalizer_t::reverse_iterator it(m_user_finalizer.rbegin()), + it_end(m_user_finalizer.rend()); it != it_end; ++it) { it->call(); diff --git a/cpp/zone.hpp.erb b/cpp/zone.hpp.erb index ac08595c..d63fae86 100644 --- a/cpp/zone.hpp.erb +++ b/cpp/zone.hpp.erb @@ -25,7 +25,7 @@ #include #ifndef MSGPACK_ZONE_CHUNK_SIZE -#define MSGPACK_ZONE_CHUNK_SIZE 8*1024 +#define MSGPACK_ZONE_CHUNK_SIZE 1024 #endif namespace msgpack { @@ -44,19 +44,19 @@ public: void push_finalizer(void (*func)(void* obj, void* user), T* obj, void* user); public: - object_nil* nnil() { return new (alloc()) object_nil(); } - object_true* ntrue() { return new (alloc()) object_true(); } - object_false* nfalse() { return new (alloc()) object_false(); } - object_u8* nu8( uint8_t v) { return new (alloc()) object_u8(v); } - object_u16* nu16(uint16_t v) { return new (alloc()) object_u16(v); } - object_u32* nu32(uint32_t v) { return new (alloc()) object_u32(v); } - object_u64* nu64(uint64_t v) { return new (alloc()) object_u64(v); } - object_i8* ni8( int8_t v) { return new (alloc()) object_i8(v); } - object_i16* ni16( int16_t v) { return new (alloc()) object_i16(v); } - object_i32* ni32( int32_t v) { return new (alloc()) object_i32(v); } - object_i64* ni64( int64_t v) { return new (alloc()) object_i64(v); } - object_float* nfloat( float v) { return new (alloc()) object_float(v); } - object_double* ndouble( double v) { return new (alloc()) object_double(v); } + object_nil* nnil () { return new (alloc()) object_nil(); } + object_true* ntrue () { return new (alloc()) object_true(); } + object_false* nfalse () { return new (alloc()) object_false(); } + object_u8* nu8 (uint8_t v) { return new (alloc()) object_u8(v); } + object_u16* nu16 (uint16_t v) { return new (alloc()) object_u16(v); } + object_u32* nu32 (uint32_t v) { return new (alloc()) object_u32(v); } + object_u64* nu64 (uint64_t v) { return new (alloc()) object_u64(v); } + object_i8* ni8 (int8_t v) { return new (alloc()) object_i8(v); } + object_i16* ni16 (int16_t v) { return new (alloc()) object_i16(v); } + object_i32* ni32 (int32_t v) { return new (alloc()) object_i32(v); } + object_i64* ni64 (int64_t v) { return new (alloc()) object_i64(v); } + object_float* nfloat (float v) { return new (alloc()) object_float(v); } + object_double* ndouble(double v) { return new (alloc()) object_double(v); } object_raw_ref* nraw_ref(void* ptr, uint32_t len) { return new (alloc()) object_raw_ref(ptr, len); } @@ -149,7 +149,7 @@ private: user_finalizer_t m_user_finalizer; private: - void resize_pool(size_t n); + void expand_chunk(); public: static void finalize_free(void* obj, void* user) @@ -173,6 +173,16 @@ inline bool zone::empty() const return m_used == 0 && m_user_finalizer.empty(); } +inline void* zone::alloc() +{ + if(m_pool.size() <= m_used/ZONE_CHUNK_SIZE) { + expand_chunk(); + } + void* data = m_pool[m_used/ZONE_CHUNK_SIZE][m_used%ZONE_CHUNK_SIZE].data; + ++m_used; + return data; +} + } // namespace msgpack