841 }
842 valueIndex++;
843 }
844 }
845 if (compatible && twoSlotKinds != null) {
846 // if there are two-slot values then make sure the incoming states can be merged
847 outer: for (int valueIndex = 0; valueIndex < entryCount; valueIndex++) {
848 if (twoSlotKinds[valueIndex] != null) {
849 assert valueIndex < virtual.entryCount() - 1 && virtual.entryKind(valueIndex) == JavaKind.Int && virtual.entryKind(valueIndex + 1) == JavaKind.Int;
850 for (int i = 0; i < states.length; i++) {
851 int object = getObject.applyAsInt(i);
852 ObjectState objectState = states[i].getObjectState(object);
853 ValueNode value = objectState.getEntry(valueIndex);
854 JavaKind valueKind = value.getStackKind();
855 if (valueKind != twoSlotKinds[valueIndex]) {
856 ValueNode nextValue = objectState.getEntry(valueIndex + 1);
857 if (value.isConstant() && value.asConstant().equals(JavaConstant.INT_0) && nextValue.isConstant() && nextValue.asConstant().equals(JavaConstant.INT_0)) {
858 // rewrite to a zero constant of the larger kind
859 debug.log("Rewriting entry %s to constant of larger size", valueIndex);
860 states[i].setEntry(object, valueIndex, ConstantNode.defaultForKind(twoSlotKinds[valueIndex], graph()));
861 states[i].setEntry(object, valueIndex + 1, ConstantNode.forConstant(JavaConstant.forIllegal(), tool.getMetaAccessProvider(), graph()));
862 } else {
863 compatible = false;
864 break outer;
865 }
866 }
867 }
868 }
869 }
870 }
871
872 if (compatible) {
873 // virtual objects are compatible: create phis for all entries that need them
874 ValueNode[] values = states[0].getObjectState(getObject.applyAsInt(0)).getEntries().clone();
875 PhiNode[] phis = getValuePhis(virtual, virtual.entryCount());
876 int valueIndex = 0;
877 while (valueIndex < values.length) {
878 for (int i = 1; i < states.length; i++) {
879 if (phis[valueIndex] == null) {
880 ValueNode field = states[i].getObjectState(getObject.applyAsInt(i)).getEntry(valueIndex);
881 if (values[valueIndex] != field) {
882 phis[valueIndex] = createValuePhi(values[valueIndex].stamp(NodeView.DEFAULT).unrestricted());
883 }
884 }
885 }
886 if (phis[valueIndex] != null && !phis[valueIndex].stamp(NodeView.DEFAULT).isCompatible(values[valueIndex].stamp(NodeView.DEFAULT))) {
887 phis[valueIndex] = createValuePhi(values[valueIndex].stamp(NodeView.DEFAULT).unrestricted());
888 }
889 if (twoSlotKinds != null && twoSlotKinds[valueIndex] != null) {
890 // skip an entry after a long/double value that occupies two int slots
891 valueIndex++;
892 phis[valueIndex] = null;
893 values[valueIndex] = ConstantNode.forConstant(JavaConstant.forIllegal(), tool.getMetaAccessProvider(), graph());
894 }
895 valueIndex++;
896 }
897
898 boolean materialized = false;
899 for (int i = 0; i < values.length; i++) {
900 PhiNode phi = phis[i];
901 if (phi != null) {
902 mergeEffects.addFloatingNode(phi, "virtualMergePhi");
903 if (virtual.entryKind(i) == JavaKind.Object) {
904 materialized |= mergeObjectEntry(getObject, states, phi, i);
905 } else {
906 for (int i2 = 0; i2 < states.length; i2++) {
907 ObjectState state = states[i2].getObjectState(getObject.applyAsInt(i2));
908 if (!state.isVirtual()) {
909 break;
910 }
911 setPhiInput(phi, i2, state.getEntry(i));
912 }
913 }
|
841 }
842 valueIndex++;
843 }
844 }
845 if (compatible && twoSlotKinds != null) {
846 // if there are two-slot values then make sure the incoming states can be merged
847 outer: for (int valueIndex = 0; valueIndex < entryCount; valueIndex++) {
848 if (twoSlotKinds[valueIndex] != null) {
849 assert valueIndex < virtual.entryCount() - 1 && virtual.entryKind(valueIndex) == JavaKind.Int && virtual.entryKind(valueIndex + 1) == JavaKind.Int;
850 for (int i = 0; i < states.length; i++) {
851 int object = getObject.applyAsInt(i);
852 ObjectState objectState = states[i].getObjectState(object);
853 ValueNode value = objectState.getEntry(valueIndex);
854 JavaKind valueKind = value.getStackKind();
855 if (valueKind != twoSlotKinds[valueIndex]) {
856 ValueNode nextValue = objectState.getEntry(valueIndex + 1);
857 if (value.isConstant() && value.asConstant().equals(JavaConstant.INT_0) && nextValue.isConstant() && nextValue.asConstant().equals(JavaConstant.INT_0)) {
858 // rewrite to a zero constant of the larger kind
859 debug.log("Rewriting entry %s to constant of larger size", valueIndex);
860 states[i].setEntry(object, valueIndex, ConstantNode.defaultForKind(twoSlotKinds[valueIndex], graph()));
861 states[i].setEntry(object, valueIndex + 1, ConstantNode.forConstant(JavaConstant.forIllegal(), tool.getMetaAccess(), graph()));
862 } else {
863 compatible = false;
864 break outer;
865 }
866 }
867 }
868 }
869 }
870 }
871
872 if (compatible) {
873 // virtual objects are compatible: create phis for all entries that need them
874 ValueNode[] values = states[0].getObjectState(getObject.applyAsInt(0)).getEntries().clone();
875 PhiNode[] phis = getValuePhis(virtual, virtual.entryCount());
876 int valueIndex = 0;
877 while (valueIndex < values.length) {
878 for (int i = 1; i < states.length; i++) {
879 if (phis[valueIndex] == null) {
880 ValueNode field = states[i].getObjectState(getObject.applyAsInt(i)).getEntry(valueIndex);
881 if (values[valueIndex] != field) {
882 phis[valueIndex] = createValuePhi(values[valueIndex].stamp(NodeView.DEFAULT).unrestricted());
883 }
884 }
885 }
886 if (phis[valueIndex] != null && !phis[valueIndex].stamp(NodeView.DEFAULT).isCompatible(values[valueIndex].stamp(NodeView.DEFAULT))) {
887 phis[valueIndex] = createValuePhi(values[valueIndex].stamp(NodeView.DEFAULT).unrestricted());
888 }
889 if (twoSlotKinds != null && twoSlotKinds[valueIndex] != null) {
890 // skip an entry after a long/double value that occupies two int slots
891 valueIndex++;
892 phis[valueIndex] = null;
893 values[valueIndex] = ConstantNode.forConstant(JavaConstant.forIllegal(), tool.getMetaAccess(), graph());
894 }
895 valueIndex++;
896 }
897
898 boolean materialized = false;
899 for (int i = 0; i < values.length; i++) {
900 PhiNode phi = phis[i];
901 if (phi != null) {
902 mergeEffects.addFloatingNode(phi, "virtualMergePhi");
903 if (virtual.entryKind(i) == JavaKind.Object) {
904 materialized |= mergeObjectEntry(getObject, states, phi, i);
905 } else {
906 for (int i2 = 0; i2 < states.length; i2++) {
907 ObjectState state = states[i2].getObjectState(getObject.applyAsInt(i2));
908 if (!state.isVirtual()) {
909 break;
910 }
911 setPhiInput(phi, i2, state.getEntry(i));
912 }
913 }
|