# HG changeset patch # User Andreas Woess # Date 1405008929 -7200 # Node ID 9fa5872291c175fb9c23cc286d333e582c1ab2ff # Parent 17f7331dcc4f032c5204bc68f1c9d4da9be547c3 Truffle: improve NodeIterator diff -r 17f7331dcc4f -r 9fa5872291c1 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Thu Jul 10 18:08:29 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Thu Jul 10 18:15:29 2014 +0200 @@ -252,58 +252,53 @@ private final class NodeIterator implements Iterator { private final Node node; - private final int childrenCount; - private int index; + private int fieldIndex; + private int arrayIndex; protected NodeIterator(Node node) { this.node = node; - this.index = 0; - this.childrenCount = childrenCount(); - } - - private int childrenCount() { - int nodeCount = childOffsets.length; - for (long fieldOffset : childrenOffsets) { - Node[] children = ((Node[]) unsafe.getObject(node, fieldOffset)); - if (children != null) { - nodeCount += children.length; - } - } - return nodeCount; - } - - private Node nodeAt(int idx) { - int nodeCount = childOffsets.length; - if (idx < nodeCount) { - return (Node) unsafe.getObject(node, childOffsets[idx]); - } else { - for (long fieldOffset : childrenOffsets) { - Node[] nodeArray = (Node[]) unsafe.getObject(node, fieldOffset); - if (idx < nodeCount + nodeArray.length) { - return nodeArray[idx - nodeCount]; - } - nodeCount += nodeArray.length; - } - } - return null; } private void forward() { - if (index < childrenCount) { - index++; + if (fieldIndex < childOffsets.length) { + fieldIndex++; + } else if (fieldIndex < childOffsets.length + childrenOffsets.length) { + if (arrayIndex + 1 < currentChildrenArrayLength()) { + arrayIndex++; + } else { + arrayIndex = 0; + do { + fieldIndex++; + } while (fieldIndex < childOffsets.length + childrenOffsets.length && currentChildrenArrayLength() == 0); + } } } public boolean hasNext() { - return index < childrenCount; + return fieldIndex < childOffsets.length || (fieldIndex < childOffsets.length + childrenOffsets.length && arrayIndex < currentChildrenArrayLength()); + } + + private Node[] currentChildrenArray() { + assert fieldIndex >= childOffsets.length && fieldIndex < childOffsets.length + childrenOffsets.length; + return (Node[]) unsafe.getObject(node, childrenOffsets[fieldIndex - childOffsets.length]); + } + + private int currentChildrenArrayLength() { + Node[] childrenArray = currentChildrenArray(); + return childrenArray != null ? childrenArray.length : 0; } public Node next() { - try { - return nodeAt(index); - } finally { - forward(); + Node next; + if (fieldIndex < childOffsets.length) { + next = (Node) unsafe.getObject(node, childOffsets[fieldIndex]); + } else if (fieldIndex < childOffsets.length + childrenOffsets.length) { + next = currentChildrenArray()[arrayIndex]; + } else { + throw new NoSuchElementException(); } + forward(); + return next; } public void remove() {