[Bf-blender-cvs] [dafbb5daf70] functions-experimental-refactor: properly align inline storage in vector and map
Jacques Lucke
noreply at git.blender.org
Sun Nov 3 11:39:38 CET 2019
Commit: dafbb5daf70e0a68ee59036fbd13da72dde608d2
Author: Jacques Lucke
Date: Sun Nov 3 11:37:10 2019 +0100
Branches: functions-experimental-refactor
https://developer.blender.org/rBdafbb5daf70e0a68ee59036fbd13da72dde608d2
properly align inline storage in vector and map
===================================================================
M source/blender/blenlib/BLI_memory_utils_cxx.h
M source/blender/blenlib/BLI_open_addressing.h
M source/blender/blenlib/BLI_vector.h
===================================================================
diff --git a/source/blender/blenlib/BLI_memory_utils_cxx.h b/source/blender/blenlib/BLI_memory_utils_cxx.h
index c64953919a4..082ce7abc59 100644
--- a/source/blender/blenlib/BLI_memory_utils_cxx.h
+++ b/source/blender/blenlib/BLI_memory_utils_cxx.h
@@ -98,6 +98,24 @@ template<typename T> struct DestructValueAtAddress {
template<typename T> using destruct_ptr = std::unique_ptr<T, DestructValueAtAddress<T>>;
+template<uint Size, uint Alignment> class alignas(Alignment) AlignedBuffer {
+ private:
+ /* Don't create an empty array. This causes problems with some compilers. */
+ static constexpr uint ActualSize = (Size > 0) ? Size : 1;
+ char m_buffer[Size];
+
+ public:
+ void *ptr()
+ {
+ return (void *)m_buffer;
+ }
+
+ const void *ptr() const
+ {
+ return (const void *)m_buffer;
+ }
+};
+
} // namespace BLI
#endif /* __BLI_MEMORY_UTILS_CXX_H__ */
diff --git a/source/blender/blenlib/BLI_open_addressing.h b/source/blender/blenlib/BLI_open_addressing.h
index 8ca5156a952..a238902c631 100644
--- a/source/blender/blenlib/BLI_open_addressing.h
+++ b/source/blender/blenlib/BLI_open_addressing.h
@@ -70,7 +70,7 @@ class OpenAddressingArray {
/* Can be used to map a hash value into the range of valid slot indices. */
uint32_t m_slot_mask;
Allocator m_allocator;
- char m_local_storage[sizeof(Item) * ItemsInSmallStorage];
+ AlignedBuffer<sizeof(Item) * ItemsInSmallStorage, alignof(Item)> m_local_storage;
public:
explicit OpenAddressingArray(uint8_t item_exponent = 0)
@@ -291,7 +291,7 @@ class OpenAddressingArray {
private:
Item *small_storage() const
{
- return reinterpret_cast<Item *>((char *)m_local_storage);
+ return reinterpret_cast<Item *>((char *)m_local_storage.ptr());
}
bool is_in_small_storage() const
diff --git a/source/blender/blenlib/BLI_vector.h b/source/blender/blenlib/BLI_vector.h
index e5ec6fb1269..07da5e7bedf 100644
--- a/source/blender/blenlib/BLI_vector.h
+++ b/source/blender/blenlib/BLI_vector.h
@@ -48,7 +48,7 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
T *m_end;
T *m_capacity_end;
Allocator m_allocator;
- char m_small_buffer[sizeof(T) * N];
+ AlignedBuffer<sizeof(T) * N, alignof(T)> m_small_buffer;
#ifndef NDEBUG
/* Storing size in debug builds, because it makes debugging much easier sometimes. */
@@ -233,6 +233,8 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
return *this;
}
+ /* This can fail, when the vector is used to build a recursive data structure.
+ See https://youtu.be/7Qgd9B1KuMQ?t=840. */
this->~Vector();
new (this) Vector(std::move(other));
@@ -531,7 +533,7 @@ template<typename T, uint N = 4, typename Allocator = GuardedAllocator> class Ve
private:
T *small_buffer() const
{
- return (T *)m_small_buffer;
+ return (T *)m_small_buffer.ptr();
}
bool is_small() const
More information about the Bf-blender-cvs
mailing list