Mercurial > hg > truffle
changeset 22080:65e9fbb40e51
avoid publishing unadopted children in node replacement to fix potential race
author | Andreas Woess <andreas.woess@oracle.com> |
---|---|
date | Thu, 13 Aug 2015 18:22:22 +0200 |
parents | 14ee5048c76e |
children | ff531952a91c |
files | truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java |
diffstat | 2 files changed, 12 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- 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);
--- 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; }