6670459: Fix Node::dump() performance
authorkvn
Thu, 06 Mar 2008 20:58:16 -0800
changeset 213 a5fd1de03461
parent 212 cd4963e67949
child 214 c5d9b4456687
6670459: Fix Node::dump() performance Summary: dump full ideal graph takes forever. Reviewed-by: never, rasbold
hotspot/src/share/vm/opto/node.cpp
hotspot/src/share/vm/opto/node.hpp
--- a/hotspot/src/share/vm/opto/node.cpp	Thu Mar 06 10:53:33 2008 -0800
+++ b/hotspot/src/share/vm/opto/node.cpp	Thu Mar 06 20:58:16 2008 -0800
@@ -1462,26 +1462,6 @@
 }
 
 //------------------------------dump_nodes-------------------------------------
-
-// Helper class  for dump_nodes. Wraps an old and new VectorSet.
-class OldNewVectorSet : public StackObj {
-   Arena*    _node_arena;
-   VectorSet _old_vset, _new_vset;
-   VectorSet* select(Node* n) {
-     return _node_arena->contains(n) ? &_new_vset : &_old_vset;
-   }
-  public:
-  OldNewVectorSet(Arena* node_arena, ResourceArea* area) :
-     _node_arena(node_arena),
-     _old_vset(area), _new_vset(area) {}
-
-  void set(Node* n)      { select(n)->set(n->_idx); }
-  bool test_set(Node* n) { return select(n)->test_set(n->_idx) != 0; }
-  bool test(Node* n)     { return select(n)->test(n->_idx) != 0; }
-  void del(Node* n)      { (*select(n)) >>= n->_idx; }
-};
-
-
 static void dump_nodes(const Node* start, int d, bool only_ctrl) {
   Node* s = (Node*)start; // remove const
   if (NotANode(s)) return;
@@ -1489,75 +1469,41 @@
   uint depth = (uint)ABS(d);
   int direction = d;
   Compile* C = Compile::current();
-  ResourceArea *area = Thread::current()->resource_area();
-  Node_Stack      stack(area, MIN2(depth, C->unique() >> 1));
-  OldNewVectorSet dumped(C->node_arena(), area);
-  OldNewVectorSet on_stack(C->node_arena(), area);
-
-  on_stack.set(s);
-  stack.push(s, 0);
-  if (direction < 0) {
-    dumped.set(s);
-    s->dump();
-  }
-
-  // Do a depth first walk over edges
-  while (stack.is_nonempty()) {
-    Node* tp  = stack.node();
-    uint  idx = stack.index();
-    uint  limit;
-    // Limit depth
-    if (stack.size() < depth) {
-      limit = direction > 0 ? tp->len() : tp->outcnt();
-    } else {
-      limit = 0; // reached depth limit.
-    }
-    if (idx >= limit) {
-      // no more arcs to visit
-      if (direction > 0 && !dumped.test_set(tp)) tp->dump();
-      on_stack.del(tp);
-      stack.pop();
-    } else {
-      // process the "idx"th arc
-      stack.set_index(idx + 1);
-      Node* n = direction > 0 ? tp->in(idx) : tp->raw_out(idx);
+  GrowableArray <Node *> nstack(C->unique());
 
-      if (NotANode(n))  continue;
-      // do not recurse through top or the root (would reach unrelated stuff)
-      if (n->is_Root() || n->is_top())  continue;
-      if (only_ctrl && !n->is_CFG()) continue;
+  nstack.append(s);
+  int begin = 0;
+  int end = 0;
+  for(uint i = 0; i < depth; i++) {
+    end = nstack.length();
+    for(int j = begin; j < end; j++) {
+      Node* tp  = nstack.at(j);
+      uint limit = direction > 0 ? tp->len() : tp->outcnt();
+      for(uint k = 0; k < limit; k++) {
+        Node* n = direction > 0 ? tp->in(k) : tp->raw_out(k);
 
-      if (!on_stack.test(n)) { // forward arc
-        if (direction < 0 && !dumped.test_set(n)) n->dump();
-        stack.push(n, 0);
-        on_stack.set(n);
-      } else {  // back or cross arc
-        // print loop if there are no phis or regions in the mix
-        bool found_loop_breaker = false;
-        int k;
-        for (k = stack.size() - 1; k >= 0; k--) {
-          Node* m = stack.node_at(k);
-          if (m->is_Phi() || m->is_Region() || m->is_Root() || m->is_Start()) {
-            found_loop_breaker = true;
-            break;
-          }
-          if (m == n) // Found loop head
-            break;
-        }
-        assert(k >= 0, "n must be on stack");
+        if (NotANode(n))  continue;
+        // do not recurse through top or the root (would reach unrelated stuff)
+        if (n->is_Root() || n->is_top())  continue;
+        if (only_ctrl && !n->is_CFG()) continue;
 
-        if (!found_loop_breaker) {
-          tty->print("# %s LOOP FOUND:", only_ctrl ? "CONTROL" : "DATA");
-          for (int i = stack.size() - 1; i >= k; i--) {
-            Node* m = stack.node_at(i);
-            bool mnew = C->node_arena()->contains(m);
-            tty->print(" %s%d:%s", (mnew? "": "o"), m->_idx, m->Name());
-            if (i != 0) tty->print(direction > 0? " <-": " ->");
-          }
-          tty->cr();
+        bool on_stack = nstack.contains(n);
+        if (!on_stack) {
+          nstack.append(n);
         }
       }
     }
+    begin = end;
+  }
+  end = nstack.length();
+  if (direction > 0) {
+    for(int j = end-1; j >= 0; j--) {
+      nstack.at(j)->dump();
+    }
+  } else {
+    for(int j = 0; j < end; j++) {
+      nstack.at(j)->dump();
+    }
   }
 }
 
--- a/hotspot/src/share/vm/opto/node.hpp	Thu Mar 06 10:53:33 2008 -0800
+++ b/hotspot/src/share/vm/opto/node.hpp	Thu Mar 06 20:58:16 2008 -0800
@@ -1384,7 +1384,7 @@
     _inode_top->indx = i;
   }
   uint size_max() const { return (uint)pointer_delta(_inode_max, _inodes,  sizeof(INode)); } // Max size
-  uint size() const { return (uint)pointer_delta(_inode_top, _inodes,  sizeof(INode)) + 1; } // Current size
+  uint size() const { return (uint)pointer_delta((_inode_top+1), _inodes,  sizeof(INode)); } // Current size
   bool is_nonempty() const { return (_inode_top >= _inodes); }
   bool is_empty() const { return (_inode_top < _inodes); }
   void clear() { _inode_top = _inodes - 1; } // retain storage