diff --git a/tree_node.cpp b/tree_node.cpp index 94f029d6b..caf86e33b 100644 --- a/tree_node.cpp +++ b/tree_node.cpp @@ -2,12 +2,31 @@ #include "expression_node.h" void TreeNode::release() { - printf("release of %d\n", m_identifier); + printf("releasing of %d(%p)\n", m_identifier, this); m_referenceCounter--; if (m_referenceCounter == 0) { +#if 0 for (TreeNode * child : directChildren()) { + // BUG FIXME + // Here, if we end up delete-ing the node + // then the 'next child' is wrong... child->release(); } +#endif + if (numberOfChildren() != 0) { + int lastIdentifier = lastDescendant()->identifier(); + TreeNode * child = this; + do { + bool childWillBeDeleted = (child->m_referenceCounter == 1); + child->release(); + if (!childWillBeDeleted) { + printf("Incrementing iterator\n"); + child = child->next(); + } else { + printf("Keeping iterator\n"); + } + } while (child->identifier() != lastIdentifier); + } printf("DELETE %d(%p)\n", m_identifier, this); delete this; diff --git a/tree_node.h b/tree_node.h index 5d764026f..573cc3a50 100644 --- a/tree_node.h +++ b/tree_node.h @@ -9,6 +9,12 @@ #include +/* What's in a TreeNode, really? + * - a vtable + * - an identifier + * - a reference counter + */ + class TreeNode { //friend class TreeReference; // friend class TreePool; @@ -75,7 +81,7 @@ public: } #endif - virtual size_t size() const { + virtual size_t size() const { // Consider making this full abstract? return sizeof(TreeNode); } @@ -135,6 +141,21 @@ public: return node; } + TreeNode * lastDescendant() const { + TreeNode * node = const_cast(this); + + int remainingNodesToVisit = 0; + while (true) { + remainingNodesToVisit += node->numberOfChildren(); + if (remainingNodesToVisit == 0) { + return node; + } + node = node->next(); + remainingNodesToVisit--; + } + return node; + } + size_t deepSize() const { // TODO: Error handling return diff --git a/tree_pool.cpp b/tree_pool.cpp index c6c7479ec..f31dc8471 100644 --- a/tree_pool.cpp +++ b/tree_pool.cpp @@ -68,6 +68,8 @@ static inline void insert(char * source, char * destination, size_t length) { } } } + } else { + assert(false); // TODO: Implement this case } } @@ -76,6 +78,7 @@ void TreePool::move(TreeNode * source, TreeNode * destination) { return; } insert(reinterpret_cast(source), reinterpret_cast(destination), source->deepSize()); + // Here, update the nodeForIdentifier array } #if TREE_LOGGING diff --git a/tree_pool.h b/tree_pool.h index fbf11f375..98c8939ae 100644 --- a/tree_pool.h +++ b/tree_pool.h @@ -9,6 +9,17 @@ class TreePool { public: TreePool() : m_lastIdentifier(0), m_cursor(m_buffer) {} + template + TreeNode * createTreeNode() { + // Find a new identifier + // Find a memory location for node + } + void discardTreeNode(TreeNode * node) { + // Reclaim node's identifier + // then dealloc node's memory + // Then call the destructor on node + } + int generateIdentifier() { printf("Generating identifier %d\n", m_lastIdentifier); /* For now we're not bothering with making sure the identifiers are indeed