comparison 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
comparison
equal deleted inserted replaced
11949:f2fbdf89a1a5 11950:be0a33a631fa
345 } 345 }
346 346
347 return nodes; 347 return nodes;
348 } 348 }
349 349
350 public static void replaceChild(Node parent, Node oldChild, Node newChild) { 350 public static boolean replaceChild(Node parent, Node oldChild, Node newChild) {
351 NodeClass nodeClass = NodeClass.get(parent.getClass()); 351 NodeClass nodeClass = NodeClass.get(parent.getClass());
352 352
353 for (long fieldOffset : nodeClass.getChildOffsets()) { 353 for (long fieldOffset : nodeClass.getChildOffsets()) {
354 if (unsafe.getObject(parent, fieldOffset) == oldChild) { 354 if (unsafe.getObject(parent, fieldOffset) == oldChild) {
355 assert assertAssignable(nodeClass, fieldOffset, newChild); 355 assert assertAssignable(nodeClass, fieldOffset, newChild);
356 unsafe.putObject(parent, fieldOffset, newChild); 356 unsafe.putObject(parent, fieldOffset, newChild);
357 return; 357 return true;
358 } 358 }
359 } 359 }
360 360
361 for (long fieldOffset : nodeClass.getChildrenOffsets()) { 361 for (long fieldOffset : nodeClass.getChildrenOffsets()) {
362 Object arrayObject = unsafe.getObject(parent, fieldOffset); 362 Object arrayObject = unsafe.getObject(parent, fieldOffset);
365 Node[] array = (Node[]) arrayObject; 365 Node[] array = (Node[]) arrayObject;
366 for (int i = 0; i < array.length; i++) { 366 for (int i = 0; i < array.length; i++) {
367 if (array[i] == oldChild) { 367 if (array[i] == oldChild) {
368 assert assertAssignable(nodeClass, fieldOffset, newChild); 368 assert assertAssignable(nodeClass, fieldOffset, newChild);
369 array[i] = newChild; 369 array[i] = newChild;
370 return; 370 return true;
371 } 371 }
372 } 372 }
373 } 373 }
374 } 374 }
375 return false;
375 } 376 }
376 377
377 private static boolean assertAssignable(NodeClass clazz, long fieldOffset, Object newValue) { 378 private static boolean assertAssignable(NodeClass clazz, long fieldOffset, Object newValue) {
378 if (newValue == null) { 379 if (newValue == null) {
379 return true; 380 return true;
796 sb.append(" ___" + srcText + "___"); 797 sb.append(" ___" + srcText + "___");
797 return sb.toString(); 798 return sb.toString();
798 } 799 }
799 return ""; 800 return "";
800 } 801 }
802
803 public static boolean verify(Node root) {
804 Iterable<Node> children = root.getChildren();
805 for (Node child : children) {
806 if (child != null) {
807 if (child.getParent() != root) {
808 throw new AssertionError(toStringWithClass(child) + ": actual parent=" + toStringWithClass(child.getParent()) + " expected parent=" + toStringWithClass(root));
809 }
810 verify(child);
811 }
812 }
813 return true;
814 }
815
816 private static String toStringWithClass(Object obj) {
817 return obj == null ? "null" : obj + "(" + obj.getClass().getName() + ")";
818 }
801 } 819 }