comparison truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java @ 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 78c3d3d8d86e
children dc83cc1f94f2 3aad794eec0e
comparison
equal deleted inserted replaced
22079:14ee5048c76e 22080:65e9fbb40e51
177 public final void adoptChildren() { 177 public final void adoptChildren() {
178 CompilerDirectives.transferToInterpreterAndInvalidate(); 178 CompilerDirectives.transferToInterpreterAndInvalidate();
179 adoptHelper(); 179 adoptHelper();
180 } 180 }
181 181
182 private void adoptHelper(final Node newChild) { 182 void adoptHelper(final Node newChild) {
183 assert newChild != null; 183 assert newChild != null;
184 if (newChild == this) { 184 if (newChild == this) {
185 throw new IllegalStateException("The parent of a node can never be the node itself."); 185 throw new IllegalStateException("The parent of a node can never be the node itself.");
186 } 186 }
187 newChild.parent = this; 187 newChild.parent = this;
278 newNode.assignSourceSection(sourceSection); 278 newNode.assignSourceSection(sourceSection);
279 } 279 }
280 // (aw) need to set parent *before* replace, so that (unsynchronized) getRootNode() 280 // (aw) need to set parent *before* replace, so that (unsynchronized) getRootNode()
281 // will always find the root node 281 // will always find the root node
282 newNode.parent = this.parent; 282 newNode.parent = this.parent;
283 if (NodeUtil.replaceChild(this.parent, this, newNode)) { 283 if (!NodeUtil.replaceChild(this.parent, this, newNode, true)) {
284 this.parent.adoptHelper(newNode);
285 } else {
286 this.parent.adoptUnadoptedHelper(newNode); 284 this.parent.adoptUnadoptedHelper(newNode);
287 } 285 }
288 reportReplace(this, newNode, reason); 286 reportReplace(this, newNode, reason);
289 onReplace(newNode, reason); 287 onReplace(newNode, reason);
290 } 288 }