< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PartialEscapeClosure.java

Print this page




 992                             uniqueVirtualObject = false;
 993                         }
 994                         ensureVirtual &= objectState.getEnsureVirtualized();
 995                         virtualInputs++;
 996                     }
 997                 }
 998             }
 999             if (virtualInputs == states.length) {
1000                 if (uniqueVirtualObject) {
1001                     // all inputs refer to the same object: just make the phi node an alias
1002                     addVirtualAlias(virtualObjs[0], phi);
1003                     mergeEffects.deleteNode(phi);
1004                     return false;
1005                 } else {
1006                     // all inputs are virtual: check if they're compatible and without identity
1007                     boolean compatible = true;
1008                     VirtualObjectNode firstVirtual = virtualObjs[0];
1009                     for (int i = 0; i < states.length; i++) {
1010                         VirtualObjectNode virtual = virtualObjs[i];
1011 
1012                         boolean identitySurvives = virtual.hasIdentity() &&
1013                                         // check whether we trivially see that this is the only
1014                                         // reference to this allocation
1015                                         !isSingleUsageAllocation(getPhiValueAt(phi, i));
1016 
1017                         if (identitySurvives || !firstVirtual.type().equals(virtual.type()) || firstVirtual.entryCount() != virtual.entryCount()) {
1018                             compatible = false;
1019                             break;
1020                         }
1021                         if (!states[0].getObjectState(firstVirtual).locksEqual(states[i].getObjectState(virtual))) {
1022                             compatible = false;
1023                             break;
1024                         }
1025                     }
1026                     if (compatible) {












1027                         VirtualObjectNode virtual = getValueObjectVirtual(phi, virtualObjs[0]);
1028                         mergeEffects.addFloatingNode(virtual, "valueObjectNode");
1029                         mergeEffects.deleteNode(phi);
1030                         if (virtual.getObjectId() == -1) {
1031                             int id = virtualObjects.size();
1032                             virtualObjects.add(virtual);
1033                             virtual.setObjectId(id);
1034                         }
1035 
1036                         int[] virtualObjectIds = new int[states.length];
1037                         for (int i = 0; i < states.length; i++) {
1038                             virtualObjectIds[i] = virtualObjs[i].getObjectId();
1039                         }
1040                         boolean materialized = mergeObjectStates(virtual.getObjectId(), virtualObjectIds, states);
1041                         addVirtualAlias(virtual, virtual);
1042                         addVirtualAlias(virtual, phi);
1043                         return materialized;
1044                     }
1045                 }
1046             }


1052                     VirtualObjectNode virtual = virtualObjs[i];
1053                     if (virtual != null) {
1054                         Block predecessor = getPredecessor(i);
1055                         if (!ensureVirtual && states[i].getObjectState(virtual).isVirtual()) {
1056                             // we can materialize if not all inputs are "ensureVirtualized"
1057                             states[i].getObjectState(virtual).setEnsureVirtualized(false);
1058                         }
1059                         materialized |= ensureMaterialized(states[i], virtual.getObjectId(), predecessor.getEndNode(), blockEffects.get(predecessor), COUNTER_MATERIALIZATIONS_PHI);
1060                     }
1061                 }
1062             }
1063             for (int i = 0; i < states.length; i++) {
1064                 VirtualObjectNode virtual = virtualObjs[i];
1065                 if (virtual != null) {
1066                     setPhiInput(phi, i, getAliasAndResolve(states[i], virtual));
1067                 }
1068             }
1069             return materialized;
1070         }
1071 
1072         private boolean isSingleUsageAllocation(ValueNode value) {
1073             /*
1074              * If the phi input is an allocation, we know that it is a "fresh" value, i.e., that
1075              * this is a value that will only appear through this source, and cannot appear anywhere
1076              * else. If the phi is also the only usage of this input, we know that no other place
1077              * can check object identity against it, so it is safe to lose the object identity here.
1078              */
1079             return value instanceof AllocatedObjectNode && value.hasExactlyOneUsage();




















1080         }
1081     }
1082 
1083     public ObjectState getObjectState(PartialEscapeBlockState<?> state, ValueNode value) {
1084         if (value == null) {
1085             return null;
1086         }
1087         if (value.isAlive() && !aliases.isNew(value)) {
1088             ValueNode object = aliases.get(value);
1089             return object instanceof VirtualObjectNode ? state.getObjectStateOptional((VirtualObjectNode) object) : null;
1090         } else {
1091             if (value instanceof VirtualObjectNode) {
1092                 return state.getObjectStateOptional((VirtualObjectNode) value);
1093             }
1094             return null;
1095         }
1096     }
1097 
1098     public ValueNode getAlias(ValueNode value) {
1099         if (value != null && !(value instanceof VirtualObjectNode)) {




 992                             uniqueVirtualObject = false;
 993                         }
 994                         ensureVirtual &= objectState.getEnsureVirtualized();
 995                         virtualInputs++;
 996                     }
 997                 }
 998             }
 999             if (virtualInputs == states.length) {
1000                 if (uniqueVirtualObject) {
1001                     // all inputs refer to the same object: just make the phi node an alias
1002                     addVirtualAlias(virtualObjs[0], phi);
1003                     mergeEffects.deleteNode(phi);
1004                     return false;
1005                 } else {
1006                     // all inputs are virtual: check if they're compatible and without identity
1007                     boolean compatible = true;
1008                     VirtualObjectNode firstVirtual = virtualObjs[0];
1009                     for (int i = 0; i < states.length; i++) {
1010                         VirtualObjectNode virtual = virtualObjs[i];
1011 
1012                         if (!firstVirtual.type().equals(virtual.type()) || firstVirtual.entryCount() != virtual.entryCount()) {





1013                             compatible = false;
1014                             break;
1015                         }
1016                         if (!states[0].getObjectState(firstVirtual).locksEqual(states[i].getObjectState(virtual))) {
1017                             compatible = false;
1018                             break;
1019                         }
1020                     }
1021                     if (compatible) {
1022                         for (int i = 0; i < states.length; i++) {
1023                             VirtualObjectNode virtual = virtualObjs[i];
1024                             /*
1025                              * check whether we trivially see that this is the only reference to
1026                              * this allocation
1027                              */
1028                             if (virtual.hasIdentity() && !isSingleUsageAllocation(getPhiValueAt(phi, i), virtualObjs, states[i])) {
1029                                 compatible = false;
1030                             }
1031                         }
1032                     }
1033                     if (compatible) {
1034                         VirtualObjectNode virtual = getValueObjectVirtual(phi, virtualObjs[0]);
1035                         mergeEffects.addFloatingNode(virtual, "valueObjectNode");
1036                         mergeEffects.deleteNode(phi);
1037                         if (virtual.getObjectId() == -1) {
1038                             int id = virtualObjects.size();
1039                             virtualObjects.add(virtual);
1040                             virtual.setObjectId(id);
1041                         }
1042 
1043                         int[] virtualObjectIds = new int[states.length];
1044                         for (int i = 0; i < states.length; i++) {
1045                             virtualObjectIds[i] = virtualObjs[i].getObjectId();
1046                         }
1047                         boolean materialized = mergeObjectStates(virtual.getObjectId(), virtualObjectIds, states);
1048                         addVirtualAlias(virtual, virtual);
1049                         addVirtualAlias(virtual, phi);
1050                         return materialized;
1051                     }
1052                 }
1053             }


1059                     VirtualObjectNode virtual = virtualObjs[i];
1060                     if (virtual != null) {
1061                         Block predecessor = getPredecessor(i);
1062                         if (!ensureVirtual && states[i].getObjectState(virtual).isVirtual()) {
1063                             // we can materialize if not all inputs are "ensureVirtualized"
1064                             states[i].getObjectState(virtual).setEnsureVirtualized(false);
1065                         }
1066                         materialized |= ensureMaterialized(states[i], virtual.getObjectId(), predecessor.getEndNode(), blockEffects.get(predecessor), COUNTER_MATERIALIZATIONS_PHI);
1067                     }
1068                 }
1069             }
1070             for (int i = 0; i < states.length; i++) {
1071                 VirtualObjectNode virtual = virtualObjs[i];
1072                 if (virtual != null) {
1073                     setPhiInput(phi, i, getAliasAndResolve(states[i], virtual));
1074                 }
1075             }
1076             return materialized;
1077         }
1078 
1079         private boolean isSingleUsageAllocation(ValueNode value, VirtualObjectNode[] virtualObjs, PartialEscapeBlockState<?> state) {
1080             /*
1081              * If the phi input is an allocation, we know that it is a "fresh" value, i.e., that
1082              * this is a value that will only appear through this source, and cannot appear anywhere
1083              * else. If the phi is also the only usage of this input, we know that no other place
1084              * can check object identity against it, so it is safe to lose the object identity here.
1085              */
1086             if (!(value instanceof AllocatedObjectNode && value.hasExactlyOneUsage())) {
1087                 return false;
1088             }
1089 
1090             /*
1091              * Check that the state only references the one virtual object from the Phi.
1092              */
1093             VirtualObjectNode singleVirtual = null;
1094             for (int v = 0; v < virtualObjs.length; v++) {
1095                 if (state.contains(virtualObjs[v])) {
1096                     if (singleVirtual == null) {
1097                         singleVirtual = virtualObjs[v];
1098                     } else if (singleVirtual != virtualObjs[v]) {
1099                         /*
1100                          * More than one virtual object is visible in the object state.
1101                          */
1102                         return false;
1103                     }
1104                 }
1105             }
1106             return true;
1107         }
1108     }
1109 
1110     public ObjectState getObjectState(PartialEscapeBlockState<?> state, ValueNode value) {
1111         if (value == null) {
1112             return null;
1113         }
1114         if (value.isAlive() && !aliases.isNew(value)) {
1115             ValueNode object = aliases.get(value);
1116             return object instanceof VirtualObjectNode ? state.getObjectStateOptional((VirtualObjectNode) object) : null;
1117         } else {
1118             if (value instanceof VirtualObjectNode) {
1119                 return state.getObjectStateOptional((VirtualObjectNode) value);
1120             }
1121             return null;
1122         }
1123     }
1124 
1125     public ValueNode getAlias(ValueNode value) {
1126         if (value != null && !(value instanceof VirtualObjectNode)) {


< prev index next >