Blob Blame History Raw
From: Modestas Vainius <modestas@vainius.eu>
Subject: [PATCH] Memory alignment fixes

Fixes various memory alignment issues which cause generator to crash on
alignment-sensitive architectures.

Signed-off-by: Modestas Vainius <modestas@vainius.eu>

---
 generator/parser/ast.h           |    2 +-
 generator/parser/list.h          |    2 +-
 generator/parser/rpp/pp-symbol.h |    9 +++++++--
 generator/parser/rxx_allocator.h |   17 +++++++++++++++++
 generator/parser/smallobject.h   |    6 ++++++
 5 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/generator/parser/ast.h b/generator/parser/ast.h
index c213b21..90be00a 100644
--- a/generator/parser/ast.h
+++ b/generator/parser/ast.h
@@ -863,7 +863,7 @@ struct QEnumsAST : public DeclarationAST
 template <class _Tp>
 _Tp *CreateNode(pool *memory_pool)
 {
-  _Tp *node = reinterpret_cast<_Tp*>(memory_pool->allocate(sizeof(_Tp)));
+  _Tp *node = reinterpret_cast<_Tp*>(memory_pool->allocate(sizeof(_Tp), strideof(_Tp)));
   node->kind = _Tp::__node_kind;
   return node;
 }
diff --git a/generator/parser/list.h b/generator/parser/list.h
index e25a6d9..bfc5cb8 100644
--- a/generator/parser/list.h
+++ b/generator/parser/list.h
@@ -37,7 +37,7 @@ struct ListNode
 
   static ListNode *create(const Tp &element, pool *p)
   {
-    ListNode<Tp> *node = new (p->allocate(sizeof(ListNode))) ListNode();
+    ListNode<Tp> *node = new (p->allocate(sizeof(ListNode), strideof(ListNode))) ListNode();
     node->element = element;
     node->index = 0;
     node->next = node;
diff --git a/generator/parser/rpp/pp-symbol.h b/generator/parser/rpp/pp-symbol.h
index de646df..f82bd42 100644
--- a/generator/parser/rpp/pp-symbol.h
+++ b/generator/parser/rpp/pp-symbol.h
@@ -24,6 +24,11 @@ class pp_symbol
     static rxx_allocator<char>__allocator;
     return __allocator;
   }
+  static rxx_allocator<pp_fast_string> &ppfs_allocator_instance ()
+  {
+    static rxx_allocator<pp_fast_string>__ppfs_allocator;
+    return __ppfs_allocator;
+  }
 
 public:
   static int &N()
@@ -39,7 +44,7 @@ public:
     memcpy(data, __data, __size);
     data[__size] = '\0';
 
-    char *where = allocator_instance ().allocate (sizeof (pp_fast_string));
+    pp_fast_string *where = ppfs_allocator_instance ().allocate (sizeof (pp_fast_string));
     return new (where) pp_fast_string (data, __size);
   }
 
@@ -59,7 +64,7 @@ public:
     std::copy (__first, __last, data);
     data[__size] = '\0';
 
-    char *where = allocator_instance ().allocate (sizeof (pp_fast_string));
+    pp_fast_string *where = ppfs_allocator_instance ().allocate (sizeof (pp_fast_string));
     return new (where) pp_fast_string (data, __size);
   }
 
diff --git a/generator/parser/rxx_allocator.h b/generator/parser/rxx_allocator.h
index ee6bddb..1e6ccd2 100644
--- a/generator/parser/rxx_allocator.h
+++ b/generator/parser/rxx_allocator.h
@@ -31,6 +31,17 @@
 #include <cstring>
 #include <memory>
 
+// Stride calculation
+template <typename T>
+struct Tchar {
+  T t;
+  char c;
+};
+
+#define strideof(T)                            \
+  ((sizeof(Tchar<T>) > sizeof(T)) ?            \
+  sizeof(Tchar<T>)-sizeof(T) : sizeof(T))
+
 template <class _Tp> class rxx_allocator {
 public:
   typedef _Tp value_type;
@@ -89,6 +100,12 @@ public:
     return p;
   }
 
+  pointer allocate(size_type __n, size_type stride, const void* = 0) {
+    if (reinterpret_cast<size_type>(_M_current_block + _M_current_index) % stride > 0)
+      _M_current_index += stride - reinterpret_cast<size_type>(_M_current_block + _M_current_index) % stride;
+    return allocate(__n);
+  }
+
   void deallocate(pointer __p, size_type __n) {}
 
   size_type max_size() const { return size_type(-1) / sizeof(_Tp); }
diff --git a/generator/parser/smallobject.h b/generator/parser/smallobject.h
index 0debcc8..2c4f541 100644
--- a/generator/parser/smallobject.h
+++ b/generator/parser/smallobject.h
@@ -35,6 +35,7 @@ class pool
 
 public:
   inline void *allocate(std::size_t __size);
+  inline void *allocate(std::size_t __size, std::size_t __stride);
 };
 
 inline void *pool::allocate(std::size_t __size)
@@ -42,6 +43,11 @@ inline void *pool::allocate(std::size_t __size)
   return __alloc.allocate(__size);
 }
 
+inline void *pool::allocate(std::size_t __size, std::size_t __stride)
+{
+  return __alloc.allocate(__size, __stride);
+}
+
 #endif
 
 // kate: space-indent on; indent-width 2; replace-tabs on;
-- 
tg: (95a3b52..) general/memory_alignment_fix (depends on: upstream)