From cd43d84b1ebe33e69d8a48d1201216df23b0228a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 14 Aug 2018 17:31:47 +0200 Subject: [PATCH] [poincare] Fix TreeRef deletion: releaseNode shouldn't create a TreeRef --- .../include/poincare/n_ary_expression_node.h | 1 - poincare/include/poincare/tree_by_reference.h | 4 ++-- poincare/include/poincare/tree_pool.h | 2 ++ poincare/src/tree_by_reference.cpp | 14 ++------------ poincare/src/tree_node.cpp | 2 +- poincare/src/tree_pool.cpp | 16 ++++++++++++++++ 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/poincare/include/poincare/n_ary_expression_node.h b/poincare/include/poincare/n_ary_expression_node.h index 631b603ff..4dbd757d1 100644 --- a/poincare/include/poincare/n_ary_expression_node.h +++ b/poincare/include/poincare/n_ary_expression_node.h @@ -36,7 +36,6 @@ public: NAryExpression(const NAryExpressionNode * n) : Expression(n) {} using Expression::addChildAtIndexInPlace; using Expression::removeChildrenInPlace; - using Expression::removeChildrenAndDestroyInPlace; using Expression::removeChildAtIndexInPlace; using Expression::removeChildInPlace; typedef int (*ExpressionOrder)(const ExpressionNode * e1, const ExpressionNode * e2, bool canBeInterrupted); diff --git a/poincare/include/poincare/tree_by_reference.h b/poincare/include/poincare/tree_by_reference.h index 5e7586351..038102cb6 100644 --- a/poincare/include/poincare/tree_by_reference.h +++ b/poincare/include/poincare/tree_by_reference.h @@ -1,13 +1,14 @@ #ifndef POINCARE_TREE_BY_REFERENCE_H #define POINCARE_TREE_BY_REFERENCE_H -#include "tree_pool.h" +#include #include namespace Poincare { class TreeByReference { friend class TreeNode; + friend class TreePool; public: /* Constructors */ TreeByReference(const TreeByReference & tr) : m_identifier(TreePool::NoNodeIdentifier) { @@ -129,7 +130,6 @@ protected: virtual void removeChildAtIndexInPlace(int i); virtual void removeChildInPlace(TreeByReference t, int childNumberOfChildren); virtual void removeChildrenInPlace(int currentNumberOfChildren); - virtual void removeChildrenAndDestroyInPlace(int currentNumberOfChildren); int m_identifier; diff --git a/poincare/include/poincare/tree_pool.h b/poincare/include/poincare/tree_pool.h index e32b9f0dc..9af5031e2 100644 --- a/poincare/include/poincare/tree_pool.h +++ b/poincare/include/poincare/tree_pool.h @@ -69,6 +69,8 @@ public: void move(TreeNode * destination, TreeNode * source, int realNumberOfSourceChildren); void moveChildren(TreeNode * destination, TreeNode * sourceParent); + void removeChildren(TreeNode * node, int nodeNumberOfChildren); + void removeChildrenAndDestroy(TreeNode * nodeToDestroy, int nodeNumberOfChildren); TreeNode * deepCopy(TreeNode * node) { size_t size = node->deepSize(-1); diff --git a/poincare/src/tree_by_reference.cpp b/poincare/src/tree_by_reference.cpp index d329f642f..ccc6036f8 100644 --- a/poincare/src/tree_by_reference.cpp +++ b/poincare/src/tree_by_reference.cpp @@ -80,7 +80,7 @@ void TreeByReference::replaceWithAllocationFailureInPlace(int currentNumberOfChi TreeNode * staticAllocFailNode = node()->failedAllocationStaticNode(); // Release all children and delete the node in the pool - removeChildrenAndDestroyInPlace(currentNumberOfChildren); + TreePool::sharedPool()->removeChildrenAndDestroy(node(), currentNumberOfChildren); /* WARNING: If we called "p.decrementNumberOfChildren()" here, the number of * children of the parent layout would be: * -> numberOfChildren() for "dynamic trees" that have a m_numberOfChildren @@ -202,17 +202,7 @@ void TreeByReference::removeChildInPlace(TreeByReference t, int childNumberOfChi void TreeByReference::removeChildrenInPlace(int currentNumberOfChildren) { assert(!isUninitialized()); - for (int i = 0; i < currentNumberOfChildren; i++) { - TreeByReference childRef = childAtIndex(0); - TreePool::sharedPool()->move(TreePool::sharedPool()->last(), childRef.node(), childRef.numberOfChildren()); - childRef.node()->release(childRef.numberOfChildren()); - } - node()->eraseNumberOfChildren(); -} - -void TreeByReference::removeChildrenAndDestroyInPlace(int currentNumberOfChildren) { - removeChildrenInPlace(currentNumberOfChildren); - TreePool::sharedPool()->discardTreeNode(node()); + TreePool::sharedPool()->removeChildren(node(), currentNumberOfChildren); } /* Private */ diff --git a/poincare/src/tree_node.cpp b/poincare/src/tree_node.cpp index 8ec80480b..38ac52bb1 100644 --- a/poincare/src/tree_node.cpp +++ b/poincare/src/tree_node.cpp @@ -18,7 +18,7 @@ void TreeNode::release(int currentNumberOfChildren) { } m_referenceCounter--; if (m_referenceCounter == 0) { - TreeByReference(this).removeChildrenAndDestroyInPlace(currentNumberOfChildren); + TreePool::sharedPool()->removeChildrenAndDestroy(this, currentNumberOfChildren); } } diff --git a/poincare/src/tree_pool.cpp b/poincare/src/tree_pool.cpp index 85c9f4bc4..bb4f548b7 100644 --- a/poincare/src/tree_pool.cpp +++ b/poincare/src/tree_pool.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -63,6 +64,21 @@ void TreePool::moveChildren(TreeNode * destination, TreeNode * sourceParent) { moveNodes(destination, sourceParent->next(), moveSize); } +void TreePool::removeChildren(TreeNode * node, int nodeNumberOfChildren) { + for (int i = 0; i < nodeNumberOfChildren; i++) { + TreeNode * child = node->childAtIndex(0); + TreeNode * newAddress = last(); + move(newAddress, child, child->numberOfChildren()); + newAddress->release(newAddress->numberOfChildren()); + } + node->eraseNumberOfChildren(); +} + +void TreePool::removeChildrenAndDestroy(TreeNode * nodeToDestroy, int nodeNumberOfChildren) { + removeChildren(nodeToDestroy, nodeNumberOfChildren); + discardTreeNode(nodeToDestroy); +} + void TreePool::moveNodes(TreeNode * destination, TreeNode * source, size_t moveSize) { if (source == destination || moveSize == 0) { return;