[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