001 /* 002 * Copyright 2010-2015 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.kotlin.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.kotlin.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 }