From a4471e1570069a83e62aca974f69b8e0fbbdbf84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 29 Jun 2018 15:30:40 +0200 Subject: [PATCH] StaticAllocationFailureNodes are not stored in the pool --- expression_node.cpp | 4 ++-- expression_node.h | 11 +++++++++-- expression_reference.cpp | 15 +++++++-------- expression_reference.h | 3 +-- layout_node.cpp | 4 ++-- layout_node.h | 10 ++++++++-- layout_reference.cpp | 10 +++++++--- layout_reference.h | 2 +- test.cpp | 5 +---- tree_node.h | 4 ++++ tree_pool.cpp | 5 +++++ tree_pool.h | 24 +++++++++++++++++++----- tree_reference.h | 3 ++- 13 files changed, 68 insertions(+), 32 deletions(-) diff --git a/expression_node.cpp b/expression_node.cpp index f759167c6..ff3194342 100644 --- a/expression_node.cpp +++ b/expression_node.cpp @@ -2,6 +2,6 @@ #include "allocation_failed_expression_node.h" #include "expression_reference.h" -TreeNode * ExpressionNode::staticFailedAllocationStaticNode() { - return ExpressionRef::staticFailedAllocationStaticNode(); +TreeNode * ExpressionNode::FailedAllocationStaticNode() { + return ExpressionRef::FailedAllocationStaticNode(); } diff --git a/expression_node.h b/expression_node.h index 3e2ef389c..b8ccd7a88 100644 --- a/expression_node.h +++ b/expression_node.h @@ -5,8 +5,15 @@ class ExpressionNode : public TreeNode { public: - static TreeNode * staticFailedAllocationStaticNode(); - TreeNode * failedAllocationStaticNode() override { return staticFailedAllocationStaticNode(); } + static TreeNode * FailedAllocationStaticNode(); + static int AllocationFailureNodeIdentifier() { + return FailedAllocationStaticNode()->identifier(); + } + int allocationFailureNodeIdentifier() override { + return AllocationFailureNodeIdentifier(); + } + + TreeNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); } virtual float approximate() = 0; ExpressionNode * child(int i) { return static_cast(childTreeAtIndex(i)); } }; diff --git a/expression_reference.cpp b/expression_reference.cpp index d404f3155..e1fbefb11 100644 --- a/expression_reference.cpp +++ b/expression_reference.cpp @@ -2,12 +2,11 @@ #include "allocation_failed_expression_node.h" template<> -TreeNode * ExpressionRef::staticFailedAllocationStaticNode() { - static AllocationFailedExpressionRef FailureRef; - return FailureRef.node(); -} - -template<> -ExpressionReference ExpressionRef::staticFailedAllocationStaticRef() { - return ExpressionReference(staticFailedAllocationStaticNode()); +TreeNode * ExpressionRef::FailedAllocationStaticNode() { + static AllocationFailedExpressionNode FailureNode; + if (FailureNode.identifier() >= -1) { + int newIdentifier = TreePool::sharedPool()->registerStaticNode(&FailureNode); + FailureNode.rename(newIdentifier); + } + return &FailureNode; } diff --git a/expression_reference.h b/expression_reference.h index af349de29..eaaf93370 100644 --- a/expression_reference.h +++ b/expression_reference.h @@ -16,8 +16,7 @@ public: return ExpressionReference(this->node()); } - static ExpressionReference staticFailedAllocationStaticRef(); - static TreeNode * staticFailedAllocationStaticNode(); + static TreeNode * FailedAllocationStaticNode(); ExpressionReference childAtIndex(int i) { return ExpressionReference(TreeReference::treeChildAtIndex(i).node()); diff --git a/layout_node.cpp b/layout_node.cpp index 092d3ea2a..064a2ca9a 100644 --- a/layout_node.cpp +++ b/layout_node.cpp @@ -2,8 +2,8 @@ #include "allocation_failed_layout_node.h" #include "layout_reference.h" -TreeNode * LayoutNode::staticFailedAllocationStaticNode() { - return LayoutRef::staticFailedAllocationStaticNode(); +TreeNode * LayoutNode::FailedAllocationStaticNode() { + return LayoutRef::FailedAllocationStaticNode(); } void LayoutNode::draw() { diff --git a/layout_node.h b/layout_node.h index f81211f57..7aa421a7e 100644 --- a/layout_node.h +++ b/layout_node.h @@ -7,8 +7,14 @@ class LayoutCursor; class LayoutNode : public TreeNode { public: - static TreeNode * staticFailedAllocationStaticNode(); - TreeNode * failedAllocationStaticNode() override { return staticFailedAllocationStaticNode(); } + static TreeNode * FailedAllocationStaticNode(); + TreeNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); } + static int AllocationFailureNodeIdentifier() { + return FailedAllocationStaticNode()->identifier(); + } + int allocationFailureNodeIdentifier() override { + return AllocationFailureNodeIdentifier(); + } /* Hierarchy */ LayoutNode * parent() const { return static_cast(parentTree()); } diff --git a/layout_reference.cpp b/layout_reference.cpp index 2c4c93726..42c6455d8 100644 --- a/layout_reference.cpp +++ b/layout_reference.cpp @@ -5,9 +5,13 @@ #include "char_layout_node.h" template<> -TreeNode * LayoutRef::staticFailedAllocationStaticNode() { - static AllocationFailedLayoutRef FailureRef; - return FailureRef.node(); +TreeNode * LayoutRef::FailedAllocationStaticNode() { + static AllocationFailedLayoutNode FailureNode; + if (FailureNode.identifier() >= -1) { + int newIdentifier = TreePool::sharedPool()->registerStaticNode(&FailureNode); + FailureNode.rename(newIdentifier); + } + return &FailureNode; } template diff --git a/layout_reference.h b/layout_reference.h index 495c33801..521a41997 100644 --- a/layout_reference.h +++ b/layout_reference.h @@ -18,7 +18,7 @@ public: return LayoutReference(this->node()); } - static TreeNode * staticFailedAllocationStaticNode(); + static TreeNode * FailedAllocationStaticNode(); LayoutCursor cursor() const; diff --git a/test.cpp b/test.cpp index 866ed9ebc..a6cb1ea3f 100644 --- a/test.cpp +++ b/test.cpp @@ -122,7 +122,6 @@ void testPoolExpressionAllocationFail() { AdditionRef a(f11, f3); float result = a.approximate(); assert(result == -1); - assert(ExpressionRef::staticFailedAllocationStaticNode()->retainCount() == 3); f1.replaceWith(f11); float result2 = a1.approximate(); @@ -200,7 +199,6 @@ void testPoolLayoutAllocationFail() { // Fill the pool for size 256 CharLayoutRef char1('a'); - LayoutRef::staticFailedAllocationStaticNode(); CharLayoutRef char2('b'); CharLayoutRef char3('a'); CharLayoutRef char4('b'); @@ -226,8 +224,7 @@ void runTest(test t) { int main() { printf("\n*******************\nStart running tests\n*******************\n\n"); - ExpressionRef::staticFailedAllocationStaticNode(); - assert(TreePool::sharedPool()->numberOfNodes() == 1); + assert(TreePool::sharedPool()->numberOfNodes() == 0); runTest(testAddition); runTest(testPoolEmpties); runTest(testCursorCreateAndRetain); diff --git a/tree_node.h b/tree_node.h index 7abdc8251..556b25121 100644 --- a/tree_node.h +++ b/tree_node.h @@ -31,6 +31,10 @@ public: assert(false); return nullptr; } + virtual int allocationFailureNodeIdentifier() { + assert(false); + return -1; + } // Node operations virtual void init(float f) {} diff --git a/tree_pool.cpp b/tree_pool.cpp index 90b32cad3..88ff0270a 100644 --- a/tree_pool.cpp +++ b/tree_pool.cpp @@ -7,6 +7,11 @@ TreePool * TreePool::sharedPool() { } TreeNode * TreePool::node(int identifier) const { + if (identifier < 0) { + int index = indexOfStaticNode(identifier); + assert(index >= 0 && index < MaxNumberOfStaticNodes); + return m_staticNodes[index]; + } assert(identifier >= 0 && identifier <= MaxNumberOfNodes); return m_nodeForIdentifier[identifier]; } diff --git a/tree_pool.h b/tree_pool.h index 9d17f17bd..65526c14e 100644 --- a/tree_pool.h +++ b/tree_pool.h @@ -8,7 +8,6 @@ class TreePool { friend class TreeNode; public: - static constexpr int AllocationFailureIdentifier = 0; static TreePool * sharedPool(); // Node @@ -19,13 +18,13 @@ public: TreeNode * createTreeNode() { int nodeIdentifier = generateIdentifier(); if (nodeIdentifier == -1) { - T::staticFailedAllocationStaticNode()->retain(); - return T::staticFailedAllocationStaticNode(); + T::FailedAllocationStaticNode()->retain(); + return T::FailedAllocationStaticNode(); } void * ptr = alloc(sizeof(T)); if (ptr == nullptr) { - T::staticFailedAllocationStaticNode()->retain(); - return T::staticFailedAllocationStaticNode(); + T::FailedAllocationStaticNode()->retain(); + return T::FailedAllocationStaticNode(); } T * node = new(ptr) T(); node->rename(nodeIdentifier); @@ -47,6 +46,16 @@ public: return copy; } + int registerStaticNode(TreeNode * node) { + int nodeID = 0; + while (m_staticNodes[nodeID] != nullptr && nodeID < MaxNumberOfStaticNodes) { + nodeID++; + } + assert(nodeID < MaxNumberOfStaticNodes); + m_staticNodes[nodeID] = node; + return identifierOfStaticNodeAtIndex(nodeID); + } + // Debug void log(); @@ -62,6 +71,7 @@ public: private: constexpr static int BufferSize = 256; constexpr static int MaxNumberOfNodes = BufferSize/sizeof(TreeNode); + constexpr static int MaxNumberOfStaticNodes = 2; // TreeNode void discardTreeNode(TreeNode * node) { @@ -79,6 +89,9 @@ private: registerNode(node); } + int identifierOfStaticNodeAtIndex(int index) const { return - (index+2);} // We do not want positive indexes that are reserved for pool nodes, and -1 is reserved for node initialisation. + int indexOfStaticNode(int id) const { return -id-2;} + // Iterators TreeNode * first() const { return reinterpret_cast(const_cast(m_buffer)); } @@ -153,6 +166,7 @@ private: char * m_cursor; char m_buffer[BufferSize]; TreeNode * m_nodeForIdentifier[MaxNumberOfNodes]; + TreeNode * m_staticNodes[MaxNumberOfStaticNodes]; }; #endif diff --git a/tree_reference.h b/tree_reference.h index d538d1733..4627a5de8 100644 --- a/tree_reference.h +++ b/tree_reference.h @@ -39,7 +39,8 @@ public: TreeReference clone() const { TreeNode * myNode = node(); if (myNode->isAllocationFailure()) { - return TreeReference(TreePool::sharedPool()->node(TreePool::AllocationFailureIdentifier)); + int allocationFailureNodeId = myNode->allocationFailureNodeIdentifier(); + return TreeReference(TreePool::sharedPool()->node(allocationFailureNodeId)); } TreeNode * nodeCopy = TreePool::sharedPool()->deepCopy(myNode); return TreeReference(nodeCopy);