Mercurial > hg > graal-jvmci-8
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 } |