# HG changeset patch # User Andreas Woess # Date 1439482942 -7200 # Node ID 65e9fbb40e51142db66225c44146b87495861311 # Parent 14ee5048c76e5af6be98d5a810669cb3e484d1ad avoid publishing unadopted children in node replacement to fix potential race diff -r 14ee5048c76e -r 65e9fbb40e51 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Thu Aug 13 16:59:39 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Thu Aug 13 18:22:22 2015 +0200 @@ -179,7 +179,7 @@ adoptHelper(); } - private void adoptHelper(final Node newChild) { + void adoptHelper(final Node newChild) { assert newChild != null; if (newChild == this) { throw new IllegalStateException("The parent of a node can never be the node itself."); @@ -280,9 +280,7 @@ // (aw) need to set parent *before* replace, so that (unsynchronized) getRootNode() // will always find the root node newNode.parent = this.parent; - if (NodeUtil.replaceChild(this.parent, this, newNode)) { - this.parent.adoptHelper(newNode); - } else { + if (!NodeUtil.replaceChild(this.parent, this, newNode, true)) { this.parent.adoptUnadoptedHelper(newNode); } reportReplace(this, newNode, reason); diff -r 14ee5048c76e -r 65e9fbb40e51 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Thu Aug 13 16:59:39 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Thu Aug 13 18:22:22 2015 +0200 @@ -199,12 +199,19 @@ } public static boolean replaceChild(Node parent, Node oldChild, Node newChild) { + return replaceChild(parent, oldChild, newChild, false); + } + + static boolean replaceChild(Node parent, Node oldChild, Node newChild, boolean adopt) { CompilerAsserts.neverPartOfCompilation(); NodeClass nodeClass = parent.getNodeClass(); for (NodeFieldAccessor nodeField : nodeClass.getChildFields()) { if (nodeField.getObject(parent) == oldChild) { assert assertAssignable(nodeField, newChild); + if (adopt) { + parent.adoptHelper(newChild); + } nodeField.putObject(parent, newChild); return true; } @@ -217,6 +224,9 @@ for (int i = 0; i < array.length; i++) { if (array[i] == oldChild) { assert assertAssignable(nodeField, newChild); + if (adopt) { + parent.adoptHelper(newChild); + } array[i] = newChild; return true; }