diff --git a/poincare/include/poincare/tree_node.h b/poincare/include/poincare/tree_node.h index 19508a8a5..f21c2efa6 100644 --- a/poincare/include/poincare/tree_node.h +++ b/poincare/include/poincare/tree_node.h @@ -18,6 +18,9 @@ * - a reference counter */ +/* CAUTION: To make node operations faster, the pool needs all adresses and + * sizes of TreeNodes to be a multiple of 4. */ + namespace Poincare { #if __EMSCRIPTEN__ diff --git a/poincare/src/symbol.cpp b/poincare/src/symbol.cpp index 64ef5cc90..f4c2c4540 100644 --- a/poincare/src/symbol.cpp +++ b/poincare/src/symbol.cpp @@ -14,8 +14,19 @@ namespace Poincare { constexpr char Symbol::k_ans[]; +/* TreePool uses adresses and sizes that are multiples of 4 in order to make + * node moves faster.*/ +size_t SymbolSize(size_t nameLength) { + size_t realSize = sizeof(SymbolNode)+nameLength+1; + size_t alignment = 4; + size_t modulo = realSize % alignment; + size_t result = realSize + (modulo == 0 ? 0 : alignment - modulo); + assert(result % 4 == 0); + return result; +} + size_t SymbolNode::size() const { - return sizeof(SymbolNode)+strlen(m_name)+1; + return SymbolSize(strlen(m_name)); } ExpressionNode::Sign SymbolNode::sign() const { @@ -148,7 +159,7 @@ Evaluation SymbolNode::templatedApproximate(Context& context, Preferences::An return e.approximateToEvaluation(context, angleUnit); } -Symbol::Symbol(const char * name, int length) : Expression(TreePool::sharedPool()->createTreeNode(sizeof(SymbolNode)+length+1)) { +Symbol::Symbol(const char * name, int length) : Expression(TreePool::sharedPool()->createTreeNode(SymbolSize(length))) { node()->setName(name, length); } diff --git a/poincare/src/tree_pool.cpp b/poincare/src/tree_pool.cpp index cceb37f72..f43d3be69 100644 --- a/poincare/src/tree_pool.cpp +++ b/poincare/src/tree_pool.cpp @@ -115,6 +115,7 @@ void TreePool::treeLog(std::ostream & stream) { #endif int TreePool::numberOfNodes() const { + ((TreePool *) this)->log(); int count = 0; TreeNode * firstNode = first(); TreeNode * lastNode = last();