diff graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @ 11950:be0a33a631fa

Truffle: fix node rewrite issue that can occur when a currently executing node is replaced in a recursive call.
author Andreas Woess <andreas.woess@jku.at>
date Wed, 09 Oct 2013 22:21:49 +0200
parents 873da100d113
children d9c34e8337f4
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Wed Oct 09 20:03:43 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Wed Oct 09 22:21:49 2013 +0200
@@ -347,14 +347,14 @@
         return nodes;
     }
 
-    public static void replaceChild(Node parent, Node oldChild, Node newChild) {
+    public static boolean replaceChild(Node parent, Node oldChild, Node newChild) {
         NodeClass nodeClass = NodeClass.get(parent.getClass());
 
         for (long fieldOffset : nodeClass.getChildOffsets()) {
             if (unsafe.getObject(parent, fieldOffset) == oldChild) {
                 assert assertAssignable(nodeClass, fieldOffset, newChild);
                 unsafe.putObject(parent, fieldOffset, newChild);
-                return;
+                return true;
             }
         }
 
@@ -367,11 +367,12 @@
                     if (array[i] == oldChild) {
                         assert assertAssignable(nodeClass, fieldOffset, newChild);
                         array[i] = newChild;
-                        return;
+                        return true;
                     }
                 }
             }
         }
+        return false;
     }
 
     private static boolean assertAssignable(NodeClass clazz, long fieldOffset, Object newValue) {
@@ -798,4 +799,21 @@
         }
         return "";
     }
+
+    public static boolean verify(Node root) {
+        Iterable<Node> children = root.getChildren();
+        for (Node child : children) {
+            if (child != null) {
+                if (child.getParent() != root) {
+                    throw new AssertionError(toStringWithClass(child) + ": actual parent=" + toStringWithClass(child.getParent()) + " expected parent=" + toStringWithClass(root));
+                }
+                verify(child);
+            }
+        }
+        return true;
+    }
+
+    private static String toStringWithClass(Object obj) {
+        return obj == null ? "null" : obj + "(" + obj.getClass().getName() + ")";
+    }
 }