Eliminate recursion in ZoneSplayTree traversal.
authormikhail.naganov@gmail.com <mikhail.naganov@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 21 Sep 2009 07:12:38 +0000 (07:12 +0000)
committermikhail.naganov@gmail.com <mikhail.naganov@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 21 Sep 2009 07:12:38 +0000 (07:12 +0000)
Convert the code to be similar with JS version. Recursive traversal is dangerous as it can cause stack exhaustion on deep trees.

Review URL: http://codereview.chromium.org/211024

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2939 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/zone-inl.h
src/zone.h

index b3141a4..121ba19 100644 (file)
@@ -276,12 +276,19 @@ void ZoneSplayTree<C>::Splay(const Key& key) {
 }
 
 
-template <typename Node, class Callback>
-static void DoForEach(Node* node, Callback* callback) {
-  if (node == NULL) return;
-  DoForEach<Node, Callback>(node->left(), callback);
-  callback->Call(node->key(), node->value());
-  DoForEach<Node, Callback>(node->right(), callback);
+template <typename Config> template <class Callback>
+void ZoneSplayTree<Config>::ForEach(Callback* callback) {
+  // Pre-allocate some space for tiny trees.
+  ZoneList<Node*> nodes_to_visit(10);
+  nodes_to_visit.Add(root_);
+  int pos = 0;
+  while (pos < nodes_to_visit.length()) {
+    Node* node = nodes_to_visit[pos++];
+    if (node == NULL) continue;
+    callback->Call(node->key(), node->value());
+    nodes_to_visit.Add(node->left());
+    nodes_to_visit.Add(node->right());
+  }
 }
 
 
index cdbab32..4e4f1d7 100644 (file)
@@ -204,10 +204,6 @@ class ZoneScope BASE_EMBEDDED {
 };
 
 
-template <typename Node, class Callback>
-static void DoForEach(Node* node, Callback* callback);
-
-
 // A zone splay tree.  The config type parameter encapsulates the
 // different configurations of a concrete splay tree:
 //
@@ -297,9 +293,7 @@ class ZoneSplayTree : public ZoneObject {
   };
 
   template <class Callback>
-  void ForEach(Callback* c) {
-    DoForEach<typename ZoneSplayTree<Config>::Node, Callback>(root_, c);
-  }
+  void ForEach(Callback* callback);
 
  private:
   Node* root_;