Mercurial > hg > truffle
comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @ 17399:5787218bad91
Truffle: implemented recursive node iterator and node streams for the graal runtime.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Thu, 09 Oct 2014 17:25:18 +0200 |
parents | 846c059e3ecf |
children | c88ab4f1f04a |
comparison
equal
deleted
inserted
replaced
17398:9e1ec84d2899 | 17399:5787218bad91 |
---|---|
342 | 342 |
343 static Iterator<Node> makeIterator(Node node) { | 343 static Iterator<Node> makeIterator(Node node) { |
344 return NodeClass.get(node.getClass()).makeIterator(node); | 344 return NodeClass.get(node.getClass()).makeIterator(node); |
345 } | 345 } |
346 | 346 |
347 public static Iterator<Node> makeRecursiveIterator(Node node) { | |
348 return new RecursiveNodeIterator(node); | |
349 } | |
350 | |
351 private final static class RecursiveNodeIterator implements Iterator<Node> { | |
352 private final List<Iterator<Node>> iteratorStack = new ArrayList<>(); | |
353 | |
354 public RecursiveNodeIterator(final Node node) { | |
355 iteratorStack.add(new Iterator<Node>() { | |
356 | |
357 private boolean visited; | |
358 | |
359 public void remove() { | |
360 throw new UnsupportedOperationException(); | |
361 } | |
362 | |
363 public Node next() { | |
364 if (visited) { | |
365 throw new NoSuchElementException(); | |
366 } | |
367 visited = true; | |
368 return node; | |
369 } | |
370 | |
371 public boolean hasNext() { | |
372 return !visited; | |
373 } | |
374 }); | |
375 } | |
376 | |
377 public boolean hasNext() { | |
378 return peekIterator() != null; | |
379 } | |
380 | |
381 public Node next() { | |
382 Iterator<Node> iterator = peekIterator(); | |
383 if (iterator == null) { | |
384 throw new NoSuchElementException(); | |
385 } | |
386 | |
387 Node node = iterator.next(); | |
388 if (node != null) { | |
389 Iterator<Node> childIterator = makeIterator(node); | |
390 if (childIterator.hasNext()) { | |
391 iteratorStack.add(childIterator); | |
392 } | |
393 } | |
394 return node; | |
395 } | |
396 | |
397 private Iterator<Node> peekIterator() { | |
398 int tos = iteratorStack.size() - 1; | |
399 while (tos >= 0) { | |
400 Iterator<Node> iterable = iteratorStack.get(tos); | |
401 if (iterable.hasNext()) { | |
402 return iterable; | |
403 } else { | |
404 iteratorStack.remove(tos--); | |
405 } | |
406 } | |
407 return null; | |
408 } | |
409 | |
410 public void remove() { | |
411 throw new UnsupportedOperationException(); | |
412 } | |
413 } | |
414 | |
347 private static long[] toLongArray(List<Long> list) { | 415 private static long[] toLongArray(List<Long> list) { |
348 long[] array = new long[list.size()]; | 416 long[] array = new long[list.size()]; |
349 for (int i = 0; i < list.size(); i++) { | 417 for (int i = 0; i < list.size(); i++) { |
350 array[i] = list.get(i); | 418 array[i] = list.get(i); |
351 } | 419 } |
604 }); | 672 }); |
605 return nodeList; | 673 return nodeList; |
606 } | 674 } |
607 | 675 |
608 public static int countNodes(Node root) { | 676 public static int countNodes(Node root) { |
609 return countNodes(root, null, false); | 677 Iterator<Node> nodeIterator = makeRecursiveIterator(root); |
678 int count = 0; | |
679 while (nodeIterator.hasNext()) { | |
680 nodeIterator.next(); | |
681 count++; | |
682 } | |
683 return count; | |
610 } | 684 } |
611 | 685 |
612 public static int countNodes(Node root, NodeCountFilter filter) { | 686 public static int countNodes(Node root, NodeCountFilter filter) { |
613 return countNodes(root, filter, false); | 687 Iterator<Node> nodeIterator = makeRecursiveIterator(root); |
614 } | 688 int count = 0; |
615 | 689 while (nodeIterator.hasNext()) { |
616 public static int countNodes(Node root, NodeCountFilter filter, boolean visitInlinedCallNodes) { | 690 Node node = nodeIterator.next(); |
617 NodeCountVisitor nodeCount = new NodeCountVisitor(filter, visitInlinedCallNodes); | 691 if (node != null && filter.isCounted(node)) { |
618 root.accept(nodeCount); | 692 count++; |
619 return nodeCount.nodeCount; | 693 } |
694 } | |
695 return count; | |
620 } | 696 } |
621 | 697 |
622 public interface NodeCountFilter { | 698 public interface NodeCountFilter { |
623 | 699 |
624 boolean isCounted(Node node); | 700 boolean isCounted(Node node); |
625 | |
626 } | |
627 | |
628 private static final class NodeCountVisitor implements NodeVisitor { | |
629 | |
630 private final boolean visitInlinedCallNodes; | |
631 int nodeCount; | |
632 private final NodeCountFilter filter; | |
633 | |
634 private NodeCountVisitor(NodeCountFilter filter, boolean visitInlinedCallNodes) { | |
635 this.filter = filter; | |
636 this.visitInlinedCallNodes = visitInlinedCallNodes; | |
637 } | |
638 | |
639 @Override | |
640 public boolean visit(Node node) { | |
641 if (filter == null || filter.isCounted(node)) { | |
642 nodeCount++; | |
643 } | |
644 | |
645 if (visitInlinedCallNodes && node instanceof DirectCallNode) { | |
646 DirectCallNode call = (DirectCallNode) node; | |
647 if (call.isInlined()) { | |
648 Node target = ((RootCallTarget) call.getCurrentCallTarget()).getRootNode(); | |
649 if (target != null) { | |
650 target.accept(this); | |
651 } | |
652 } | |
653 } | |
654 | |
655 return true; | |
656 } | |
657 | 701 |
658 } | 702 } |
659 | 703 |
660 public static String printCompactTreeToString(Node node) { | 704 public static String printCompactTreeToString(Node node) { |
661 StringWriter out = new StringWriter(); | 705 StringWriter out = new StringWriter(); |