diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-02-15 13:46:13 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-02-15 13:46:13 +0300 |
commit | 6371fccdbe34ac214f54a8843dc6d2c9f1e05d92 (patch) | |
tree | 1f66cf8e45765573ecd3a4cd5b07128fdec4fecd | |
parent | 318d3b9ab40bac7b22d10d3e00428c433670d721 (diff) |
Cycles: Fix guarded allocator issues on Windows
The issue was caused by static vectors allocating some internal
data using rebound element allocator for them, which was causing
access to a non-initialized statistics objects and was failing a
lot when switching Blender to a fully guarded allocation.
Additionally, we were not able to free that internal memory before
Blender exits, which was causing false-positive memory leak prints.
Now we're not using GuardedAllocator for those proxy containers.
Ideally this should be done as a GuardedAllocator::rebind, but
it didn't work for vector<bool> because it seems some internal
parts are converting bool to char32_t, which either makes it so
we can't use GuardedAllocator for those vectors or the compiler
get's confused when we're trying explicitly allow GuardedAllocator
for rebind<char32_t>.
This with current approach we should be fine for the release.
-rw-r--r-- | intern/cycles/util/util_guarded_allocator.h | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/intern/cycles/util/util_guarded_allocator.h b/intern/cycles/util/util_guarded_allocator.h index 484aa3a8cce..ad1eb6f657f 100644 --- a/intern/cycles/util/util_guarded_allocator.h +++ b/intern/cycles/util/util_guarded_allocator.h @@ -123,6 +123,34 @@ public: inline bool operator==(GuardedAllocator const& /*other*/) { return true; } inline bool operator!=(GuardedAllocator const& other) { return !operator==(other); } + +#ifdef _MSC_VER + /* Welcome to the black magic here. + * + * The issue is that MSVC C++ allocates container proxy on any + * vector initialization, including static vectors which don't + * have any data yet. This leads to several issues: + * + * - Static objects initialization fiasco (global_stats from + * util_stats.h might not be initialized yet). + * - If main() function changes allocator type (for example, + * this might happen with `blender --debug-memory`) nobody + * will know how to convert already allocated memory to a new + * guarded allocator. + * + * Here we work this around by making it so container proxy does + * not use guarded allocation. A bit fragile, unfortunately. + */ + template<> + struct rebind<std::_Container_proxy> { + typedef std::allocator<std::_Container_proxy> other; + }; + + operator std::allocator<std::_Container_proxy>() const + { + return std::allocator<std::_Container_proxy>(); + } +#endif }; /* Get memory usage and peak from the guarded STL allocator. */ |