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 +using RawArray = Array; + } // 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. */ @@ -1162,6 +1159,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 IsEqual = DefaultEquality, + typename Slot = typename DefaultMapSlot::type> +using RawMap = + Map; + /** * 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 inline constexpr bool is_convertible_pointer_v = std::is_convertible_v &&std::is_pointer_v &&std::is_pointer_v; +/** + * 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 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 IsEqual = DefaultEquality, + typename Slot = typename DefaultSetSlot::type> +using RawSet = Set; + } // 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 +using RawStack = Stack; + } /* 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 +using RawVector = Vector; + } /* 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 IsEqual = DefaultEquality, + typename Slot = typename DefaultVectorSetSlot::type> +using RawVectorSet = VectorSet; + } // 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, 1, RawAllocator> arrays; +static RawVector> 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 IndexRange::as_span() const } int64_t new_size = std::max(1000, power_of_2_max_u(min_required_size)); - Array new_array(new_size); + RawArray 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
> g_graph_registry; +static RawMap
> 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 &graphs = g_graph_registry.lookup(bmain); + RawVectorSet &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 get_all_registered_graphs(Main *bmain) { - VectorSet *graphs = g_graph_registry.lookup_ptr(bmain); + RawVectorSet *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 param_names; - Vector param_types; - Vector param_data_indices; + RawVector param_names; + RawVector param_types; + RawVector param_data_indices; int data_index(int param_index) const {