Mercurial > hg > truffle
diff graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @ 16581:8be5c68a779d
Truffle: revert to previous iterator implementation, add test case
author | Andreas Woess <andreas.woess@jku.at> |
---|---|
date | Tue, 22 Jul 2014 16:32:43 +0200 |
parents | a3b0a2d61e62 |
children | 70f47dbbcabd |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Tue Jul 22 15:06:15 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Tue Jul 22 16:32:43 2014 +0200 @@ -252,53 +252,58 @@ private final class NodeIterator implements Iterator<Node> { private final Node node; - private int fieldIndex; - private int arrayIndex; + private final int childrenCount; + private int index; 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 (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); - } + if (index < childrenCount) { + index++; } } public boolean hasNext() { - 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; + return index < childrenCount; } public Node next() { - 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(); + try { + return nodeAt(index); + } finally { + forward(); } - forward(); - return next; } public void remove() {