1 /* |
1 /* |
2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
611 } |
611 } |
612 if (newSuccessor != null) { |
612 if (newSuccessor != null) { |
613 assert assertTrue(newSuccessor.predecessor == null, "unexpected non-null predecessor in new successor (%s): %s, this=%s", newSuccessor, newSuccessor.predecessor, this); |
613 assert assertTrue(newSuccessor.predecessor == null, "unexpected non-null predecessor in new successor (%s): %s, this=%s", newSuccessor, newSuccessor.predecessor, this); |
614 newSuccessor.predecessor = this; |
614 newSuccessor.predecessor = this; |
615 } |
615 } |
|
616 maybeNotifyInputChanged(this); |
616 } |
617 } |
617 } |
618 } |
618 |
619 |
619 void initialize(Graph newGraph) { |
620 void initialize(Graph newGraph) { |
620 assert assertTrue(id == INITIAL_ID, "unexpected id: %d", id); |
621 assert assertTrue(id == INITIAL_ID, "unexpected id: %d", id); |
815 } |
816 } |
816 } |
817 } |
817 |
818 |
818 private void replaceAtMatchingUsages(Node other, Predicate<Node> filter, Node toBeDeleted) { |
819 private void replaceAtMatchingUsages(Node other, Predicate<Node> filter, Node toBeDeleted) { |
819 if (filter == null) { |
820 if (filter == null) { |
820 fail("filter cannot be null"); |
821 throw fail("filter cannot be null"); |
821 } |
822 } |
822 checkReplaceWith(other); |
823 checkReplaceWith(other); |
823 int i = 0; |
824 int i = 0; |
824 while (i < this.getUsageCount()) { |
825 int usageCount = this.getUsageCount(); |
|
826 while (i < usageCount) { |
825 Node usage = this.getUsageAt(i); |
827 Node usage = this.getUsageAt(i); |
826 if (filter.test(usage)) { |
828 if (filter.test(usage)) { |
827 replaceAtUsage(other, toBeDeleted, usage); |
829 replaceAtUsage(other, toBeDeleted, usage); |
828 this.movUsageFromEndTo(i); |
830 this.movUsageFromEndTo(i); |
|
831 usageCount--; |
829 } else { |
832 } else { |
830 ++i; |
833 ++i; |
831 } |
834 } |
832 } |
835 } |
833 } |
836 } |
834 |
837 |
835 public Node getUsageAt(int index) { |
838 private Node getUsageAt(int index) { |
836 if (index == 0) { |
839 if (index == 0) { |
837 return this.usage0; |
840 return this.usage0; |
838 } else if (index == 1) { |
841 } else if (index == 1) { |
839 return this.usage1; |
842 return this.usage1; |
840 } else { |
843 } else { |
845 public void replaceAtMatchingUsages(Node other, NodePredicate usagePredicate) { |
848 public void replaceAtMatchingUsages(Node other, NodePredicate usagePredicate) { |
846 checkReplaceWith(other); |
849 checkReplaceWith(other); |
847 replaceAtMatchingUsages(other, usagePredicate, null); |
850 replaceAtMatchingUsages(other, usagePredicate, null); |
848 } |
851 } |
849 |
852 |
|
853 private void replaceAtUsagePos(Node other, Node usage, Position pos) { |
|
854 pos.initialize(usage, other); |
|
855 maybeNotifyInputChanged(usage); |
|
856 if (other != null) { |
|
857 other.addUsage(usage); |
|
858 } |
|
859 } |
|
860 |
850 public void replaceAtUsages(InputType type, Node other) { |
861 public void replaceAtUsages(InputType type, Node other) { |
851 checkReplaceWith(other); |
862 checkReplaceWith(other); |
852 for (Node usage : usages().snapshot()) { |
863 int i = 0; |
|
864 int usageCount = this.getUsageCount(); |
|
865 if (usageCount == 0) { |
|
866 return; |
|
867 } |
|
868 usages: while (i < usageCount) { |
|
869 Node usage = this.getUsageAt(i); |
853 for (Position pos : usage.inputPositions()) { |
870 for (Position pos : usage.inputPositions()) { |
854 if (pos.getInputType() == type && pos.get(usage) == this) { |
871 if (pos.getInputType() == type && pos.get(usage) == this) { |
855 pos.set(usage, other); |
872 replaceAtUsagePos(other, usage, pos); |
|
873 this.movUsageFromEndTo(i); |
|
874 usageCount--; |
|
875 continue usages; |
856 } |
876 } |
857 } |
877 } |
|
878 i++; |
|
879 } |
|
880 if (hasNoUsages()) { |
|
881 maybeNotifyZeroUsages(this); |
858 } |
882 } |
859 } |
883 } |
860 |
884 |
861 private void maybeNotifyInputChanged(Node node) { |
885 private void maybeNotifyInputChanged(Node node) { |
862 if (graph != null) { |
886 if (graph != null) { |
907 } |
931 } |
908 |
932 |
909 public void replaceFirstInput(Node oldInput, Node newInput) { |
933 public void replaceFirstInput(Node oldInput, Node newInput) { |
910 if (nodeClass.replaceFirstInput(this, oldInput, newInput)) { |
934 if (nodeClass.replaceFirstInput(this, oldInput, newInput)) { |
911 updateUsages(oldInput, newInput); |
935 updateUsages(oldInput, newInput); |
|
936 } |
|
937 } |
|
938 |
|
939 public void replaceAllInputs(Node oldInput, Node newInput) { |
|
940 while (nodeClass.replaceFirstInput(this, oldInput, newInput)) { |
|
941 updateUsages(oldInput, newInput); |
|
942 } |
|
943 } |
|
944 |
|
945 public void replaceFirstInput(Node oldInput, Node newInput, InputType type) { |
|
946 for (Position pos : inputPositions()) { |
|
947 if (pos.getInputType() == type && pos.get(this) == oldInput) { |
|
948 pos.set(this, newInput); |
|
949 } |
912 } |
950 } |
913 } |
951 } |
914 |
952 |
915 public void clearInputs() { |
953 public void clearInputs() { |
916 assert assertFalse(isDeleted(), "cannot clear inputs of deleted node"); |
954 assert assertFalse(isDeleted(), "cannot clear inputs of deleted node"); |
1056 assertTrue(pos.isInputOptional(), "non-optional input %s cannot be null in %s (fix nullness or use @OptionalInput)", pos, this); |
1094 assertTrue(pos.isInputOptional(), "non-optional input %s cannot be null in %s (fix nullness or use @OptionalInput)", pos, this); |
1057 } else { |
1095 } else { |
1058 assertFalse(input.isDeleted(), "input was deleted %s", input); |
1096 assertFalse(input.isDeleted(), "input was deleted %s", input); |
1059 assertTrue(input.isAlive(), "input is not alive yet, i.e., it was not yet added to the graph"); |
1097 assertTrue(input.isAlive(), "input is not alive yet, i.e., it was not yet added to the graph"); |
1060 assertTrue(pos.getInputType() == InputType.Unchecked || input.isAllowedUsageType(pos.getInputType()), "invalid usage type %s %s", input, pos.getInputType()); |
1098 assertTrue(pos.getInputType() == InputType.Unchecked || input.isAllowedUsageType(pos.getInputType()), "invalid usage type %s %s", input, pos.getInputType()); |
|
1099 Class<?> expectedType = pos.getType(); |
|
1100 assertTrue(expectedType.isAssignableFrom(input.getClass()), "Invalid input type for %s: expected a %s but was a %s", pos, expectedType, input.getClass()); |
1061 } |
1101 } |
1062 } |
1102 } |
1063 return true; |
1103 return true; |
1064 } |
1104 } |
1065 |
1105 |