Convert FrameMap to Kotlin and extract base logic

This commit is contained in:
Mikhael Bogdanov
2018-04-24 15:27:21 +02:00
parent 76bab8f3b0
commit 92e02e35fc
2 changed files with 70 additions and 81 deletions
@@ -20,12 +20,11 @@ import org.jetbrains.kotlin.codegen.inline.NameGenerator
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
interface BaseExpressionCodegen { interface BaseExpressionCodegen {
val frameMap: FrameMap val frameMap: FrameMapBase<*>
val visitor: InstructionAdapter val visitor: InstructionAdapter
@@ -38,10 +37,10 @@ interface BaseExpressionCodegen {
fun propagateChildReifiedTypeParametersUsages(reifiedTypeParametersUsages: ReifiedTypeParametersUsages) fun propagateChildReifiedTypeParametersUsages(reifiedTypeParametersUsages: ReifiedTypeParametersUsages)
fun pushClosureOnStack( fun pushClosureOnStack(
classDescriptor: ClassDescriptor, classDescriptor: ClassDescriptor,
putThis: Boolean, putThis: Boolean,
callGenerator: CallGenerator, callGenerator: CallGenerator,
functionReferenceReceiver: StackValue? functionReferenceReceiver: StackValue?
) )
fun markLineNumberAfterInlineIfNeeded() fun markLineNumberAfterInlineIfNeeded()
@@ -14,119 +14,109 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.kotlin.codegen; package org.jetbrains.kotlin.codegen
import com.google.common.collect.Lists; import com.google.common.collect.Lists
import com.intellij.openapi.util.Trinity; import com.intellij.openapi.util.Trinity
import gnu.trove.TObjectIntHashMap; import gnu.trove.TObjectIntHashMap
import gnu.trove.TObjectIntIterator; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.Type;
import java.util.ArrayList; import java.util.ArrayList
import java.util.Comparator;
import java.util.List;
public class FrameMap { class FrameMap : FrameMapBase<DeclarationDescriptor>()
private final TObjectIntHashMap<DeclarationDescriptor> myVarIndex = new TObjectIntHashMap<>();
private final TObjectIntHashMap<DeclarationDescriptor> myVarSizes = new TObjectIntHashMap<>();
private int myMaxIndex = 0;
public int enter(DeclarationDescriptor descriptor, Type type) { open class FrameMapBase<T : Any> {
int index = myMaxIndex; private val myVarIndex = TObjectIntHashMap<T>()
myVarIndex.put(descriptor, index); private val myVarSizes = TObjectIntHashMap<T>()
myMaxIndex += type.getSize(); var currentSize = 0
myVarSizes.put(descriptor, type.getSize()); private set
return index;
fun enter(descriptor: T, type: Type): Int {
val index = currentSize
myVarIndex.put(descriptor, index)
currentSize += type.size
myVarSizes.put(descriptor, type.size)
return index
} }
public int leave(DeclarationDescriptor descriptor) { fun leave(descriptor: T): Int {
int size = myVarSizes.get(descriptor); val size = myVarSizes.get(descriptor)
myMaxIndex -= size; currentSize -= size
myVarSizes.remove(descriptor); myVarSizes.remove(descriptor)
int oldIndex = myVarIndex.remove(descriptor); val oldIndex = myVarIndex.remove(descriptor)
if (oldIndex != myMaxIndex) { if (oldIndex != currentSize) {
throw new IllegalStateException("Descriptor can be left only if it is last: " + descriptor); throw IllegalStateException("Descriptor can be left only if it is last: $descriptor")
} }
return oldIndex; return oldIndex
} }
public int enterTemp(Type type) { fun enterTemp(type: Type): Int {
int result = myMaxIndex; val result = currentSize
myMaxIndex += type.getSize(); currentSize += type.size
return result; return result
} }
public void leaveTemp(Type type) { fun leaveTemp(type: Type) {
myMaxIndex -= type.getSize(); currentSize -= type.size
} }
public int getIndex(DeclarationDescriptor descriptor) { fun getIndex(descriptor: T): Int {
return myVarIndex.contains(descriptor) ? myVarIndex.get(descriptor) : -1; return if (myVarIndex.contains(descriptor)) myVarIndex.get(descriptor) else -1
} }
public Mark mark() { fun mark(): Mark {
return new Mark(myMaxIndex); return Mark(currentSize)
} }
public int getCurrentSize() { inner class Mark(private val myIndex: Int) {
return myMaxIndex;
}
public class Mark { fun dropTo() {
private final int myIndex; val descriptorsToDrop = ArrayList<T>()
val iterator = myVarIndex.iterator()
public Mark(int index) {
myIndex = index;
}
public void dropTo() {
List<DeclarationDescriptor> descriptorsToDrop = new ArrayList<>();
TObjectIntIterator<DeclarationDescriptor> iterator = myVarIndex.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
iterator.advance(); iterator.advance()
if (iterator.value() >= myIndex) { if (iterator.value() >= myIndex) {
descriptorsToDrop.add(iterator.key()); descriptorsToDrop.add(iterator.key())
} }
} }
for (DeclarationDescriptor declarationDescriptor : descriptorsToDrop) { for (declarationDescriptor in descriptorsToDrop) {
myVarIndex.remove(declarationDescriptor); myVarIndex.remove(declarationDescriptor)
myVarSizes.remove(declarationDescriptor); myVarSizes.remove(declarationDescriptor)
} }
myMaxIndex = myIndex; currentSize = myIndex
} }
} }
@Override override fun toString(): String {
public String toString() { val sb = StringBuilder()
StringBuilder sb = new StringBuilder();
if (myVarIndex.size() != myVarSizes.size()) { if (myVarIndex.size() != myVarSizes.size()) {
return "inconsistent"; return "inconsistent"
} }
List<Trinity<DeclarationDescriptor, Integer, Integer>> descriptors = Lists.newArrayList(); val descriptors = Lists.newArrayList<Trinity<T, Int, Int>>()
for (Object descriptor0 : myVarIndex.keys()) { for (descriptor0 in myVarIndex.keys()) {
DeclarationDescriptor descriptor = (DeclarationDescriptor) descriptor0; val descriptor = descriptor0 as T
int varIndex = myVarIndex.get(descriptor); val varIndex = myVarIndex.get(descriptor)
int varSize = myVarSizes.get(descriptor); val varSize = myVarSizes.get(descriptor)
descriptors.add(Trinity.create(descriptor, varIndex, varSize)); descriptors.add(Trinity.create(descriptor, varIndex, varSize))
} }
descriptors.sort(Comparator.comparingInt(left -> left.second)); descriptors.sortBy { left -> left.second }
sb.append("size=").append(myMaxIndex); sb.append("size=").append(currentSize)
boolean first = true; var first = true
for (Trinity<DeclarationDescriptor, Integer, Integer> t : descriptors) { for (t in descriptors) {
if (!first) { if (!first) {
sb.append(", "); sb.append(", ")
} }
first = false; first = false
sb.append(t.first).append(",i=").append(t.second).append(",s=").append(t.third); sb.append(t.first).append(",i=").append(t.second).append(",s=").append(t.third)
} }
return sb.toString(); return sb.toString()
} }
} }