diff options
-rw-r--r-- | source/blender/blenlib/BLI_array.hh | 12 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_map.hh | 20 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_memory_utils.hh | 9 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_set.hh | 17 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_stack.hh | 12 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_vector.hh | 9 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_vector_set.hh | 11 | ||||
-rw-r--r-- | source/blender/blenlib/intern/BLI_index_range.cc | 4 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph_registry.cc | 8 | ||||
-rw-r--r-- | source/blender/functions/FN_multi_function_signature.hh | 6 |
10 files changed, 81 insertions, 27 deletions
diff --git a/source/blender/blenlib/BLI_array.hh b/source/blender/blenlib/BLI_array.hh index 871038d7d85..c7b4bdc977f 100644 --- a/source/blender/blenlib/BLI_array.hh +++ b/source/blender/blenlib/BLI_array.hh @@ -53,11 +53,8 @@ template< typename T, /** * The number of values that can be stored in the array, without doing a heap allocation. - * - * When T is large, the small buffer optimization is disabled by default to avoid large - * unexpected allocations on the stack. It can still be enabled explicitly though. */ - int64_t InlineBufferCapacity = (sizeof(T) < 100) ? 4 : 0, + int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T)), /** * The allocator used by this array. Should rarely be changed, except when you don't want that * MEM_* functions are used internally. @@ -364,6 +361,13 @@ class Array { } }; +/** + * Same as a normal Array, but does not use Blender's guarded allocator. This is useful when + * allocating memory with static storage duration. + */ +template<typename T, int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))> +using RawArray = Array<T, InlineBufferCapacity, RawAllocator>; + } // namespace blender #endif /* __BLI_ARRAY_HH__ */ diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh index 2abaf814ec9..dd375272fdb 100644 --- a/source/blender/blenlib/BLI_map.hh +++ b/source/blender/blenlib/BLI_map.hh @@ -92,11 +92,8 @@ template< * The minimum number of elements that can be stored in this Map without doing a heap * allocation. This is useful when you expect to have many small maps. However, keep in mind * that (unlike vector) initializing a map has a O(n) cost in the number of slots. - * - * When Key or Value are large, the small buffer optimization is disabled by default to avoid - * large unexpected allocations on the stack. It can still be enabled explicitly though. */ - int64_t InlineBufferCapacity = (sizeof(Key) + sizeof(Value) < 100) ? 4 : 0, + int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key) + sizeof(Value)), /** * The strategy used to deal with collisions. They are defined in BLI_probing_strategies.hh. */ @@ -1163,6 +1160,21 @@ class Map { }; /** + * Same as a normal Map, but does not use Blender's guarded allocator. This is useful when + * allocating memory with static storage duration. + */ +template<typename Key, + typename Value, + int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key) + + sizeof(Value)), + typename ProbingStrategy = DefaultProbingStrategy, + typename Hash = DefaultHash<Key>, + typename IsEqual = DefaultEquality, + typename Slot = typename DefaultMapSlot<Key, Value>::type> +using RawMap = + Map<Key, Value, InlineBufferCapacity, ProbingStrategy, Hash, IsEqual, Slot, RawAllocator>; + +/** * A wrapper for std::unordered_map with the API of blender::Map. This can be used for * benchmarking. */ diff --git a/source/blender/blenlib/BLI_memory_utils.hh b/source/blender/blenlib/BLI_memory_utils.hh index 5c692850017..9f65fe0742e 100644 --- a/source/blender/blenlib/BLI_memory_utils.hh +++ b/source/blender/blenlib/BLI_memory_utils.hh @@ -419,6 +419,15 @@ template<typename From, typename To> inline constexpr bool is_convertible_pointer_v = std::is_convertible_v<From, To> &&std::is_pointer_v<From> &&std::is_pointer_v<To>; +/** + * Inline buffers for small-object-optimization should be disable by default. Otherwise we might + * get large unexpected allocations on the stack. + */ +inline constexpr int64_t default_inline_buffer_capacity(size_t element_size) +{ + return ((int64_t)element_size < 100) ? 4 : 0; +} + } // namespace blender #endif /* __BLI_MEMORY_UTILS_HH__ */ diff --git a/source/blender/blenlib/BLI_set.hh b/source/blender/blenlib/BLI_set.hh index 80e4858bbb9..90adea69e06 100644 --- a/source/blender/blenlib/BLI_set.hh +++ b/source/blender/blenlib/BLI_set.hh @@ -89,11 +89,8 @@ template< * The minimum number of elements that can be stored in this Set without doing a heap * allocation. This is useful when you expect to have many small sets. However, keep in mind * that (unlike vector) initializing a set has a O(n) cost in the number of slots. - * - * When Key is large, the small buffer optimization is disabled by default to avoid large - * unexpected allocations on the stack. It can still be enabled explicitly though. */ - int64_t InlineBufferCapacity = (sizeof(Key) < 100) ? 4 : 0, + int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key)), /** * The strategy used to deal with collisions. They are defined in BLI_probing_strategies.hh. */ @@ -821,6 +818,18 @@ template<typename Key> class StdUnorderedSetWrapper { } }; +/** + * Same as a normal Set, but does not use Blender's guarded allocator. This is useful when + * allocating memory with static storage duration. + */ +template<typename Key, + int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(Key)), + typename ProbingStrategy = DefaultProbingStrategy, + typename Hash = DefaultHash<Key>, + typename IsEqual = DefaultEquality, + typename Slot = typename DefaultSetSlot<Key>::type> +using RawSet = Set<Key, InlineBufferCapacity, ProbingStrategy, Hash, IsEqual, Slot, RawAllocator>; + } // namespace blender #endif /* __BLI_SET_HH__ */ diff --git a/source/blender/blenlib/BLI_stack.hh b/source/blender/blenlib/BLI_stack.hh index 422931862a8..75ae9df79a4 100644 --- a/source/blender/blenlib/BLI_stack.hh +++ b/source/blender/blenlib/BLI_stack.hh @@ -73,11 +73,8 @@ template< * The number of values that can be stored in this stack, without doing a heap allocation. * Sometimes it can make sense to increase this value a lot. The memory in the inline buffer is * not initialized when it is not needed. - * - * When T is large, the small buffer optimization is disabled by default to avoid large - * unexpected allocations on the stack. It can still be enabled explicitly though. */ - int64_t InlineBufferCapacity = (sizeof(T) < 100) ? 4 : 0, + int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T)), /** * The allocator used by this stack. Should rarely be changed, except when you don't want that * MEM_* is used internally. @@ -381,6 +378,13 @@ class Stack { } }; +/** + * Same as a normal Stack, but does not use Blender's guarded allocator. This is useful when + * allocating memory with static storage duration. + */ +template<typename T, int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))> +using RawStack = Stack<T, InlineBufferCapacity, RawAllocator>; + } /* namespace blender */ #endif /* __BLI_STACK_HH__ */ diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh index 11bb00c3f8d..1bb674093bb 100644 --- a/source/blender/blenlib/BLI_vector.hh +++ b/source/blender/blenlib/BLI_vector.hh @@ -70,7 +70,7 @@ template< * When T is large, the small buffer optimization is disabled by default to avoid large * unexpected allocations on the stack. It can still be enabled explicitly though. */ - int64_t InlineBufferCapacity = (sizeof(T) < 100) ? 4 : 0, + int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T)), /** * The allocator used by this vector. Should rarely be changed, except when you don't want that * MEM_* is used internally. @@ -824,6 +824,13 @@ class Vector { #undef UPDATE_VECTOR_SIZE +/** + * Same as a normal Vector, but does not use Blender's guarded allocator. This is useful when + * allocating memory with static storage duration. + */ +template<typename T, int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))> +using RawVector = Vector<T, InlineBufferCapacity, RawAllocator>; + } /* namespace blender */ #endif /* __BLI_VECTOR_HH__ */ diff --git a/source/blender/blenlib/BLI_vector_set.hh b/source/blender/blenlib/BLI_vector_set.hh index 7573b77cdf7..f007d41118f 100644 --- a/source/blender/blenlib/BLI_vector_set.hh +++ b/source/blender/blenlib/BLI_vector_set.hh @@ -732,6 +732,17 @@ class VectorSet { } }; +/** + * Same as a normal VectorSet, but does not use Blender's guarded allocator. This is useful when + * allocating memory with static storage duration. + */ +template<typename Key, + typename ProbingStrategy = DefaultProbingStrategy, + typename Hash = DefaultHash<Key>, + typename IsEqual = DefaultEquality, + typename Slot = typename DefaultVectorSetSlot<Key>::type> +using RawVectorSet = VectorSet<Key, ProbingStrategy, Hash, IsEqual, Slot, RawAllocator>; + } // namespace blender #endif /* __BLI_VECTOR_SET_HH__ */ diff --git a/source/blender/blenlib/intern/BLI_index_range.cc b/source/blender/blenlib/intern/BLI_index_range.cc index a906416b491..43c6265a17d 100644 --- a/source/blender/blenlib/intern/BLI_index_range.cc +++ b/source/blender/blenlib/intern/BLI_index_range.cc @@ -24,7 +24,7 @@ namespace blender { -static Vector<Array<int64_t, 0, RawAllocator>, 1, RawAllocator> arrays; +static RawVector<RawArray<int64_t, 0>> arrays; static int64_t current_array_size = 0; static int64_t *current_array = nullptr; static std::mutex current_array_mutex; @@ -44,7 +44,7 @@ Span<int64_t> IndexRange::as_span() const } int64_t new_size = std::max<int64_t>(1000, power_of_2_max_u(min_required_size)); - Array<int64_t, 0, RawAllocator> new_array(new_size); + RawArray<int64_t, 0> new_array(new_size); for (int64_t i = 0; i < new_size; i++) { new_array[i] = i; } diff --git a/source/blender/depsgraph/intern/depsgraph_registry.cc b/source/blender/depsgraph/intern/depsgraph_registry.cc index bc3b85f9be5..c9d03e47ded 100644 --- a/source/blender/depsgraph/intern/depsgraph_registry.cc +++ b/source/blender/depsgraph/intern/depsgraph_registry.cc @@ -30,9 +30,7 @@ namespace blender { namespace deg { -/* TODO: Static variables should use RawAllocator to avoid false positives of Blender's memory leak - * detector. */ -static Map<Main *, VectorSet<Depsgraph *>> g_graph_registry; +static RawMap<Main *, RawVectorSet<Depsgraph *>> g_graph_registry; void register_graph(Depsgraph *depsgraph) { @@ -43,7 +41,7 @@ void register_graph(Depsgraph *depsgraph) void unregister_graph(Depsgraph *depsgraph) { Main *bmain = depsgraph->bmain; - VectorSet<Depsgraph *> &graphs = g_graph_registry.lookup(bmain); + RawVectorSet<Depsgraph *> &graphs = g_graph_registry.lookup(bmain); graphs.remove(depsgraph); // If this was the last depsgraph associated with the main, remove the main entry as well. @@ -54,7 +52,7 @@ void unregister_graph(Depsgraph *depsgraph) Span<Depsgraph *> get_all_registered_graphs(Main *bmain) { - VectorSet<Depsgraph *> *graphs = g_graph_registry.lookup_ptr(bmain); + RawVectorSet<Depsgraph *> *graphs = g_graph_registry.lookup_ptr(bmain); if (graphs != nullptr) { return *graphs; } diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh index 4ccceb39503..af5f61fe2ee 100644 --- a/source/blender/functions/FN_multi_function_signature.hh +++ b/source/blender/functions/FN_multi_function_signature.hh @@ -33,9 +33,9 @@ namespace blender::fn { struct MFSignature { std::string function_name; /* Use RawAllocator so that a MultiFunction can have static storage duration. */ - Vector<std::string, 4, RawAllocator> param_names; - Vector<MFParamType, 4, RawAllocator> param_types; - Vector<int, 4, RawAllocator> param_data_indices; + RawVector<std::string> param_names; + RawVector<MFParamType> param_types; + RawVector<int> param_data_indices; int data_index(int param_index) const { |