summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2013-10-09 11:02:51 -0700
committerFrancisco Jerez <[email protected]>2013-10-29 12:40:55 -0700
commitd18477deea5364847ca6d4be1ce6baa6c8c3fa9c (patch)
tree5110c2af84f244792f35e9b510994d8878a89921 /src
parent98ab905af0e0eedf0cfbd9c466f6ae587f5b20c9 (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]>
Diffstat (limited to 'src')
-rw-r--r--src/glsl/ralloc.h14
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); \
}