From: José Fonseca Date: Thu, 20 Dec 2012 15:29:09 +0000 (+0000) Subject: retrace: Split ScopedAllocator into its own header. X-Git-Url: https://git.cworth.org/git?p=apitrace;a=commitdiff_plain;h=7e35dc93a0e7d6e2e1e53ca975e59a9ee956c77b retrace: Split ScopedAllocator into its own header. It will be useful outside of retrace. --- diff --git a/retrace/retrace.hpp b/retrace/retrace.hpp index 228c813..7c8dcd5 100644 --- a/retrace/retrace.hpp +++ b/retrace/retrace.hpp @@ -28,7 +28,6 @@ #include #include -#include #include #include @@ -38,6 +37,8 @@ #include "trace_parser.hpp" #include "trace_profiler.hpp" +#include "scoped_allocator.hpp" + namespace image { class Image; @@ -51,37 +52,9 @@ extern trace::Parser parser; extern trace::Profiler profiler; -/** - * Similar to alloca(), but implemented with malloc. - */ -class ScopedAllocator +class ScopedAllocator : public ::ScopedAllocator { -private: - uintptr_t next; - public: - inline - ScopedAllocator() : - next(0) { - } - - inline void * - alloc(size_t size) { - /* Always return valid address, even when size is zero */ - size = std::max(size, sizeof(uintptr_t)); - - uintptr_t * buf = static_cast(malloc(sizeof(uintptr_t) + size)); - if (!buf) { - return NULL; - } - - *buf = next; - next = reinterpret_cast(buf); - assert((next & 1) == 0); - - return static_cast(&buf[1]); - } - /** * Allocate an array with the same dimensions as the specified value. */ @@ -89,7 +62,7 @@ public: alloc(const trace::Value *value, size_t size) { const trace::Array *array = dynamic_cast(value); if (array) { - return alloc(array->size() * size); + return ::ScopedAllocator::alloc(array->size() * size); } const trace::Null *null = dynamic_cast(value); if (null) { @@ -99,32 +72,6 @@ public: return NULL; } - /** - * Prevent this pointer from being automatically freed. - */ - template< class T > - inline void - bind(T *ptr) { - if (ptr) { - reinterpret_cast(ptr)[-1] |= 1; - } - } - - inline - ~ScopedAllocator() { - while (next) { - uintptr_t temp = *reinterpret_cast(next); - - bool bind = temp & 1; - temp &= ~1; - - if (!bind) { - free(reinterpret_cast(next)); - } - - next = temp; - } - } }; diff --git a/retrace/scoped_allocator.hpp b/retrace/scoped_allocator.hpp new file mode 100644 index 0000000..f44b74f --- /dev/null +++ b/retrace/scoped_allocator.hpp @@ -0,0 +1,101 @@ +/************************************************************************** + * + * Copyright 2011-2012 Jose Fonseca + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +#ifndef _SCOPED_ALLOCATOR_HPP_ +#define _SCOPED_ALLOCATOR_HPP_ + + +#include +#include +#include + + +/** + * Similar to alloca(), but implemented with malloc. + */ +class ScopedAllocator +{ +private: + uintptr_t next; + +public: + inline + ScopedAllocator() : + next(0) { + } + + inline void * + alloc(size_t size) { + /* Always return valid address, even when size is zero */ + size = std::max(size, sizeof(uintptr_t)); + + uintptr_t * buf = static_cast(malloc(sizeof(uintptr_t) + size)); + if (!buf) { + return NULL; + } + + *buf = next; + next = reinterpret_cast(buf); + assert((next & 1) == 0); + + return static_cast(&buf[1]); + } + + template< class T > + inline T * + alloc(size_t size = 1) { + return static_cast(alloc(sizeof(T) * size)); + } + + /** + * Prevent this pointer from being automatically freed. + */ + template< class T > + inline void + bind(T *ptr) { + if (ptr) { + reinterpret_cast(ptr)[-1] |= 1; + } + } + + inline + ~ScopedAllocator() { + while (next) { + uintptr_t temp = *reinterpret_cast(next); + + bool bind = temp & 1; + temp &= ~1; + + if (!bind) { + free(reinterpret_cast(next)); + } + + next = temp; + } + } +}; + + +#endif /* _SCOPED_ALLOCATOR_HPP_ */