Mercurial > hg > graal-jvmci-8
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() + ")"; + } }