Mercurial > hg > graal-compiler
changeset 10742:99789440ce28
Truffle: Added assertions to replaceChild.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Sat, 13 Jul 2013 17:14:23 +0200 |
parents | 00a9dbcbe431 |
children | ff6eb563a2e2 |
files | graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java |
diffstat | 1 files changed, 37 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Sat Jul 13 17:13:08 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Sat Jul 13 17:14:23 2013 +0200 @@ -352,17 +352,26 @@ public static void replaceChild(Node parent, Node oldChild, Node newChild) { NodeClass nodeClass = NodeClass.get(parent.getClass()); - for (long fieldOffset : nodeClass.childOffsets) { + long[] fieldOffsets = nodeClass.childOffsets; + for (int i = 0; i < fieldOffsets.length; i++) { + long fieldOffset = fieldOffsets[i]; if (unsafe.getObject(parent, fieldOffset) == oldChild) { + assert assertAssignable(nodeClass, parent, oldChild, newChild); unsafe.putObject(parent, fieldOffset, newChild); } } - for (long fieldOffset : nodeClass.childrenOffsets) { - Node[] array = (Node[]) unsafe.getObject(parent, fieldOffset); - if (array != null) { - for (int i = 0; i < array.length; i++) { - if (array[i] == oldChild) { - array[i] = newChild; + + long[] childrenOffsets = nodeClass.childrenOffsets; + for (int i = 0; i < childrenOffsets.length; i++) { + long fieldOffset = childrenOffsets[i]; + Object arrayObject = unsafe.getObject(parent, fieldOffset); + if (arrayObject != null) { + assert arrayObject instanceof Node[] : "Children must be instanceof Node[] "; + Node[] array = (Node[]) arrayObject; + for (int j = 0; j < array.length; j++) { + if (array[j] == oldChild) { + assert newChild != null && array.getClass().getComponentType().isAssignableFrom(newChild.getClass()) : "Array type does not match"; + array[j] = newChild; return; } } @@ -370,6 +379,26 @@ } } + private static boolean assertAssignable(NodeClass clazz, Node parent, Object oldValue, Object newValue) { + if (newValue == null) { + return true; + } + for (NodeField field : clazz.fields) { + if (field.kind != NodeFieldKind.CHILD) { + continue; + } + if (unsafe.getObject(parent, field.offset) == oldValue) { + if (!field.type.isAssignableFrom(newValue.getClass())) { + assert false : "Child class " + newValue.getClass() + " is not assignable to field " + field.type.getName() + " at " + field.name + " in "; + return false; + } else { + break; + } + } + } + return true; + } + /** Returns all declared fields in the class hierarchy. */ private static Field[] getAllFields(Class<? extends Object> clazz) { Field[] declaredFields = clazz.getDeclaredFields(); @@ -660,4 +689,5 @@ p.print(" "); } } + }