001 /*
002 * Copyright 2010-2014 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.jet.codegen.optimization.boxing;
018
019 import com.intellij.openapi.util.Pair;
020 import org.jetbrains.annotations.NotNull;
021 import org.jetbrains.annotations.Nullable;
022 import org.jetbrains.jet.codegen.AsmUtil;
023 import org.jetbrains.org.objectweb.asm.Type;
024 import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
025 import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue;
026
027 import java.util.ArrayList;
028 import java.util.HashSet;
029 import java.util.List;
030 import java.util.Set;
031
032 public class BoxedBasicValue extends BasicValue {
033 private final Set<AbstractInsnNode> associatedInsns = new HashSet<AbstractInsnNode>();
034 private final Set<Pair<AbstractInsnNode, Type>> unboxingWithCastInsns = new HashSet<Pair<AbstractInsnNode, Type>>();
035 private final AbstractInsnNode boxingInsn;
036 private final Set<Integer> associatedVariables = new HashSet<Integer>();
037 private final Set<BoxedBasicValue> mergedWith = new HashSet<BoxedBasicValue>();
038 private final Type primitiveType;
039 private final ProgressionIteratorBasicValue progressionIterator;
040 private boolean isSafeToRemove = true;
041
042 public BoxedBasicValue(
043 @NotNull Type boxedType,
044 @NotNull AbstractInsnNode boxingInsn,
045 @Nullable ProgressionIteratorBasicValue progressionIterator
046 ) {
047 super(boxedType);
048 this.primitiveType = AsmUtil.unboxType(boxedType);
049 this.boxingInsn = boxingInsn;
050 this.progressionIterator = progressionIterator;
051 }
052
053 @Override
054 public boolean equals(Object o) {
055 return this == o;
056 }
057
058 public boolean typeEquals(Object o) {
059 if (o == null || getClass() != o.getClass()) return false;
060
061 BoxedBasicValue that = (BoxedBasicValue) o;
062
063 return getType().equals(that.getType());
064 }
065
066 @Override
067 public int hashCode() {
068 return System.identityHashCode(this);
069 }
070
071 public List<AbstractInsnNode> getAssociatedInsns() {
072 return new ArrayList<AbstractInsnNode>(associatedInsns);
073 }
074
075 public void addInsn(AbstractInsnNode insnNode) {
076 associatedInsns.add(insnNode);
077 }
078
079 public void addVariableIndex(int index) {
080 associatedVariables.add(index);
081 }
082
083 public List<Integer> getVariablesIndexes() {
084 return new ArrayList<Integer>(associatedVariables);
085 }
086
087 public Type getPrimitiveType() {
088 return primitiveType;
089 }
090
091 public void addMergedWith(@NotNull BoxedBasicValue value) {
092 mergedWith.add(value);
093 }
094
095 @NotNull
096 public Iterable<BoxedBasicValue> getMergedWith() {
097 return mergedWith;
098 }
099
100 public void markAsUnsafeToRemove() {
101 isSafeToRemove = false;
102 }
103
104 public boolean isSafeToRemove() {
105 return isSafeToRemove;
106 }
107
108 public boolean isDoubleSize() {
109 return getPrimitiveType().getSize() == 2;
110 }
111
112 @NotNull
113 public AbstractInsnNode getBoxingInsn() {
114 return boxingInsn;
115 }
116
117 public boolean isFromProgressionIterator() {
118 return progressionIterator != null;
119 }
120
121 @Nullable
122 public ProgressionIteratorBasicValue getProgressionIterator() {
123 return progressionIterator;
124 }
125
126 public void addUnboxingWithCastTo(@NotNull AbstractInsnNode insn, @NotNull Type type) {
127 unboxingWithCastInsns.add(Pair.create(insn, type));
128 }
129
130 @NotNull
131 public Set<Pair<AbstractInsnNode, Type>> getUnboxingWithCastInsns() {
132 return unboxingWithCastInsns;
133 }
134 }