comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @ 10742:99789440ce28

Truffle: Added assertions to replaceChild.
author Christian Humer <christian.humer@gmail.com>
date Sat, 13 Jul 2013 17:14:23 +0200
parents 84b944726df2
children b221e31d7b0b
comparison
equal deleted inserted replaced
10741:00a9dbcbe431 10742:99789440ce28
350 } 350 }
351 351
352 public static void replaceChild(Node parent, Node oldChild, Node newChild) { 352 public static void replaceChild(Node parent, Node oldChild, Node newChild) {
353 NodeClass nodeClass = NodeClass.get(parent.getClass()); 353 NodeClass nodeClass = NodeClass.get(parent.getClass());
354 354
355 for (long fieldOffset : nodeClass.childOffsets) { 355 long[] fieldOffsets = nodeClass.childOffsets;
356 for (int i = 0; i < fieldOffsets.length; i++) {
357 long fieldOffset = fieldOffsets[i];
356 if (unsafe.getObject(parent, fieldOffset) == oldChild) { 358 if (unsafe.getObject(parent, fieldOffset) == oldChild) {
359 assert assertAssignable(nodeClass, parent, oldChild, newChild);
357 unsafe.putObject(parent, fieldOffset, newChild); 360 unsafe.putObject(parent, fieldOffset, newChild);
358 } 361 }
359 } 362 }
360 for (long fieldOffset : nodeClass.childrenOffsets) { 363
361 Node[] array = (Node[]) unsafe.getObject(parent, fieldOffset); 364 long[] childrenOffsets = nodeClass.childrenOffsets;
362 if (array != null) { 365 for (int i = 0; i < childrenOffsets.length; i++) {
363 for (int i = 0; i < array.length; i++) { 366 long fieldOffset = childrenOffsets[i];
364 if (array[i] == oldChild) { 367 Object arrayObject = unsafe.getObject(parent, fieldOffset);
365 array[i] = newChild; 368 if (arrayObject != null) {
369 assert arrayObject instanceof Node[] : "Children must be instanceof Node[] ";
370 Node[] array = (Node[]) arrayObject;
371 for (int j = 0; j < array.length; j++) {
372 if (array[j] == oldChild) {
373 assert newChild != null && array.getClass().getComponentType().isAssignableFrom(newChild.getClass()) : "Array type does not match";
374 array[j] = newChild;
366 return; 375 return;
367 } 376 }
368 } 377 }
369 } 378 }
370 } 379 }
380 }
381
382 private static boolean assertAssignable(NodeClass clazz, Node parent, Object oldValue, Object newValue) {
383 if (newValue == null) {
384 return true;
385 }
386 for (NodeField field : clazz.fields) {
387 if (field.kind != NodeFieldKind.CHILD) {
388 continue;
389 }
390 if (unsafe.getObject(parent, field.offset) == oldValue) {
391 if (!field.type.isAssignableFrom(newValue.getClass())) {
392 assert false : "Child class " + newValue.getClass() + " is not assignable to field " + field.type.getName() + " at " + field.name + " in ";
393 return false;
394 } else {
395 break;
396 }
397 }
398 }
399 return true;
371 } 400 }
372 401
373 /** Returns all declared fields in the class hierarchy. */ 402 /** Returns all declared fields in the class hierarchy. */
374 private static Field[] getAllFields(Class<? extends Object> clazz) { 403 private static Field[] getAllFields(Class<? extends Object> clazz) {
375 Field[] declaredFields = clazz.getDeclaredFields(); 404 Field[] declaredFields = clazz.getDeclaredFields();
658 p.println(); 687 p.println();
659 for (int i = 0; i < level; i++) { 688 for (int i = 0; i < level; i++) {
660 p.print(" "); 689 p.print(" ");
661 } 690 }
662 } 691 }
692
663 } 693 }