diff options
author | Francisco Jerez <[email protected]> | 2013-10-09 11:02:51 -0700 |
---|---|---|
committer | Francisco Jerez <[email protected]> | 2013-10-29 12:40:55 -0700 |
commit | d18477deea5364847ca6d4be1ce6baa6c8c3fa9c (patch) | |
tree | 5110c2af84f244792f35e9b510994d8878a89921 | |
parent | 98ab905af0e0eedf0cfbd9c466f6ae587f5b20c9 (diff) |
ralloc: Hook up C++ destructors to ralloc when necessary.
This patch makes sure that class destructors are called as they should
be when a C++ object allocated by ralloc is released.
Based on a previous patch by Kenneth Graunke, but it doesn't exhibit
the ~0.8% performance regression in shader compilation times because
we now use the HAS_TRIVIAL_DESTRUCTOR() macro to detect the typical
case where the indirect function call can be avoided because the
object's destructor doesn't need to do anything.
Reviewed-by: Ian Romanick <[email protected]>
-rw-r--r-- | src/glsl/ralloc.h | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/src/glsl/ralloc.h b/src/glsl/ralloc.h index 31682d515e6..4581a7a4e41 100644 --- a/src/glsl/ralloc.h +++ b/src/glsl/ralloc.h @@ -415,15 +415,29 @@ bool ralloc_vasprintf_append(char **str, const char *fmt, va_list args); * which is more idiomatic in C++ than calling ralloc. */ #define DECLARE_RALLOC_CXX_OPERATORS(TYPE) \ +private: \ + static void _ralloc_destructor(void *p) \ + { \ + reinterpret_cast<TYPE *>(p)->~TYPE(); \ + } \ +public: \ static void* operator new(size_t size, void *mem_ctx) \ { \ void *p = ralloc_size(mem_ctx, size); \ assert(p != NULL); \ + if (!HAS_TRIVIAL_DESTRUCTOR(TYPE)) \ + ralloc_set_destructor(p, _ralloc_destructor); \ return p; \ } \ \ static void operator delete(void *p) \ { \ + /* The object's destructor is guaranteed to have already been \ + * called by the delete operator at this point -- Make sure it's \ + * not called again. \ + */ \ + if (!HAS_TRIVIAL_DESTRUCTOR(TYPE)) \ + ralloc_set_destructor(p, NULL); \ ralloc_free(p); \ } |