comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @ 10755:b221e31d7b0b

Truffle: revise NodeUtil.replaceChild assertion
author Andreas Woess <andreas.woess@jku.at>
date Mon, 15 Jul 2013 15:26:39 +0200
parents 99789440ce28
children 7f6580db1e88
comparison
equal deleted inserted replaced
10754:4c12d3756015 10755:b221e31d7b0b
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 long[] fieldOffsets = nodeClass.childOffsets; 355 for (long fieldOffset : nodeClass.getChildOffsets()) {
356 for (int i = 0; i < fieldOffsets.length; i++) {
357 long fieldOffset = fieldOffsets[i];
358 if (unsafe.getObject(parent, fieldOffset) == oldChild) { 356 if (unsafe.getObject(parent, fieldOffset) == oldChild) {
359 assert assertAssignable(nodeClass, parent, oldChild, newChild); 357 assert assertAssignable(nodeClass, fieldOffset, newChild);
360 unsafe.putObject(parent, fieldOffset, newChild); 358 unsafe.putObject(parent, fieldOffset, newChild);
361 } 359 }
362 } 360 }
363 361
364 long[] childrenOffsets = nodeClass.childrenOffsets; 362 for (long fieldOffset : nodeClass.getChildrenOffsets()) {
365 for (int i = 0; i < childrenOffsets.length; i++) {
366 long fieldOffset = childrenOffsets[i];
367 Object arrayObject = unsafe.getObject(parent, fieldOffset); 363 Object arrayObject = unsafe.getObject(parent, fieldOffset);
368 if (arrayObject != null) { 364 if (arrayObject != null) {
369 assert arrayObject instanceof Node[] : "Children must be instanceof Node[] "; 365 assert arrayObject instanceof Node[] : "Children array must be instanceof Node[] ";
370 Node[] array = (Node[]) arrayObject; 366 Node[] array = (Node[]) arrayObject;
371 for (int j = 0; j < array.length; j++) { 367 for (int i = 0; i < array.length; i++) {
372 if (array[j] == oldChild) { 368 if (array[i] == oldChild) {
373 assert newChild != null && array.getClass().getComponentType().isAssignableFrom(newChild.getClass()) : "Array type does not match"; 369 assert assertAssignable(nodeClass, fieldOffset, newChild);
374 array[j] = newChild; 370 array[i] = newChild;
375 return;
376 } 371 }
377 } 372 }
378 } 373 }
379 } 374 }
380 } 375 }
381 376
382 private static boolean assertAssignable(NodeClass clazz, Node parent, Object oldValue, Object newValue) { 377 private static boolean assertAssignable(NodeClass clazz, long fieldOffset, Object newValue) {
383 if (newValue == null) { 378 if (newValue == null) {
384 return true; 379 return true;
385 } 380 }
386 for (NodeField field : clazz.fields) { 381 for (NodeField field : clazz.getFields()) {
387 if (field.kind != NodeFieldKind.CHILD) { 382 if (field.getOffset() == fieldOffset) {
388 continue; 383 if (field.getKind() == NodeFieldKind.CHILD) {
389 } 384 if (field.getType().isAssignableFrom(newValue.getClass())) {
390 if (unsafe.getObject(parent, field.offset) == oldValue) { 385 return true;
391 if (!field.type.isAssignableFrom(newValue.getClass())) { 386 } else {
392 assert false : "Child class " + newValue.getClass() + " is not assignable to field " + field.type.getName() + " at " + field.name + " in "; 387 assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName();
393 return false; 388 return false;
394 } else { 389 }
395 break; 390 } else if (field.getKind() == NodeFieldKind.CHILDREN) {
396 } 391 if (field.getType().getComponentType().isAssignableFrom(newValue.getClass())) {
397 } 392 return true;
398 } 393 } else {
399 return true; 394 assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName();
395 return false;
396 }
397 }
398 }
399 }
400 throw new IllegalArgumentException();
400 } 401 }
401 402
402 /** Returns all declared fields in the class hierarchy. */ 403 /** Returns all declared fields in the class hierarchy. */
403 private static Field[] getAllFields(Class<? extends Object> clazz) { 404 private static Field[] getAllFields(Class<? extends Object> clazz) {
404 Field[] declaredFields = clazz.getDeclaredFields(); 405 Field[] declaredFields = clazz.getDeclaredFields();