Simplify code for specialized BranchedValues

This commit is contained in:
Dmitry Petrov
2017-07-17 17:51:00 +03:00
parent e1a55e8dec
commit 709a7e201f
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.codegen
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
@@ -27,7 +26,7 @@ abstract class NumberLikeCompare(
left: StackValue, left: StackValue,
right: StackValue, right: StackValue,
operandType: Type, operandType: Type,
protected val opToken: IElementType private val opToken: IElementType
) : BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) { ) : BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) {
override fun patchOpcode(opcode: Int, v: InstructionAdapter): Int = override fun patchOpcode(opcode: Int, v: InstructionAdapter): Int =
NumberCompare.patchOpcode(opcode, v, opToken, operandType) NumberCompare.patchOpcode(opcode, v, opToken, operandType)
@@ -130,102 +129,51 @@ class BoxedToPrimitiveEquality private constructor(
private val boxedType = arg1.type private val boxedType = arg1.type
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) { override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
if (jumpIfFalse) { if (arg2!!.canHaveSideEffects()) {
jumpIfFalse(v, jumpLabel) val tmp = frameMap.enterTemp(operandType)
doJump(
v, jumpLabel, jumpIfFalse,
{
arg1.put(boxedType, v)
arg2.put(operandType, v)
v.store(tmp, operandType)
},
{ v.load(tmp, operandType) }
)
frameMap.leaveTemp(operandType)
} }
else { else {
jumpIfTrue(v, jumpLabel) doJump(
v, jumpLabel, jumpIfFalse,
{ arg1.put(boxedType, v) },
{ arg2.put(operandType, v) }
)
} }
} }
private fun jumpIfTrue(v: InstructionAdapter, jumpLabel: Label) { private inline fun doJump(
if (arg2!!.canHaveSideEffects()) { v: InstructionAdapter,
jumpIfTrueWithPossibleSideEffects(v, jumpLabel) jumpLabel: Label,
return jumpIfFalse: Boolean,
} putArg1: () -> Unit,
putArg2: () -> Unit
val notNullLabel = Label() ) {
val endLabel = Label()
arg1.put(boxedType, v)
AsmUtil.dup(v, boxedType)
v.ifnonnull(notNullLabel)
AsmUtil.pop(v, boxedType)
v.goTo(endLabel)
v.mark(notNullLabel)
coerce(boxedType, operandType, v)
arg2.put(operandType, v)
v.visitJumpInsn(patchOpcode(negatedOperations[opcode]!!, v), jumpLabel)
v.mark(endLabel)
}
private fun jumpIfTrueWithPossibleSideEffects(v: InstructionAdapter, jumpLabel: Label) {
val notNullLabel = Label() val notNullLabel = Label()
val endLabel = Label() val endLabel = Label()
arg1.put(boxedType, v) putArg1()
arg2!!.put(operandType, v)
val tempArg2 = frameMap.enterTemp(operandType)
v.store(tempArg2, operandType)
AsmUtil.dup(v, boxedType) AsmUtil.dup(v, boxedType)
v.ifnonnull(notNullLabel) v.ifnonnull(notNullLabel)
AsmUtil.pop(v, boxedType) AsmUtil.pop(v, boxedType)
v.goTo(endLabel) if (jumpIfFalse) v.goTo(jumpLabel) else v.goTo(endLabel)
v.mark(notNullLabel) v.mark(notNullLabel)
coerce(boxedType, operandType, v) coerce(boxedType, operandType, v)
v.load(tempArg2, operandType) putArg2()
v.visitJumpInsn(patchOpcode(negatedOperations[opcode]!!, v), jumpLabel) v.visitJumpInsn(patchOpcode(if (jumpIfFalse) opcode else negatedOperations[opcode]!!, v), jumpLabel)
frameMap.leaveTemp(operandType)
v.mark(endLabel) v.mark(endLabel)
}
private fun jumpIfFalse(v: InstructionAdapter, jumpLabel: Label) {
if (arg2!!.canHaveSideEffects()) {
jumpIfFalseWithPossibleSideEffects(v, jumpLabel)
return
}
val notNullLabel = Label()
arg1.put(boxedType, v)
AsmUtil.dup(v, boxedType)
v.ifnonnull(notNullLabel)
AsmUtil.pop(v, boxedType)
v.goTo(jumpLabel)
v.mark(notNullLabel)
coerce(boxedType, operandType, v)
arg2.put(operandType, v)
v.visitJumpInsn(patchOpcode(opcode, v), jumpLabel)
}
private fun jumpIfFalseWithPossibleSideEffects(v: InstructionAdapter, jumpLabel: Label) {
val notNullLabel = Label()
arg1.put(boxedType, v)
arg2!!.put(operandType, v)
val tempArg2 = frameMap.enterTemp(operandType)
v.store(tempArg2, operandType)
AsmUtil.dup(v, boxedType)
v.ifnonnull(notNullLabel)
AsmUtil.pop(v, boxedType)
v.goTo(jumpLabel)
v.mark(notNullLabel)
coerce(boxedType, operandType, v)
v.load(tempArg2, operandType)
v.visitJumpInsn(patchOpcode(opcode, v), jumpLabel)
frameMap.leaveTemp(operandType)
} }
companion object { companion object {
@@ -254,59 +202,53 @@ class BoxedToPrimitiveEquality private constructor(
} }
} }
abstract class PrimitiveToSomethingEquality
protected constructor(
leftPrimitive: StackValue,
right: StackValue,
primitiveType: Type
) : NumberLikeCompare(leftPrimitive, right, primitiveType, KtTokens.EQEQ) {
protected val primitiveType = leftPrimitive.type
protected val rightType = right.type
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
val notNullLabel = Label()
val endLabel = Label()
arg1.put(primitiveType, v)
arg2!!.put(rightType, v)
AsmUtil.dup(v, rightType)
jumpIfCanCompareTopWithPrimitive(v, notNullLabel)
AsmUtil.pop(v, rightType)
AsmUtil.pop(v, primitiveType)
if (jumpIfFalse) v.goTo(jumpLabel) else v.goTo(endLabel)
v.mark(notNullLabel)
coerceRightToPrimitive(v)
v.visitJumpInsn(patchOpcode(if (jumpIfFalse) opcode else negatedOperations[opcode]!!, v), jumpLabel)
v.mark(endLabel)
}
protected abstract fun jumpIfCanCompareTopWithPrimitive(v: InstructionAdapter, label: Label)
protected abstract fun coerceRightToPrimitive(v: InstructionAdapter)
}
class PrimitiveToBoxedEquality private constructor( class PrimitiveToBoxedEquality private constructor(
leftPrimitive: StackValue, leftPrimitive: StackValue,
rightBoxed: StackValue, rightBoxed: StackValue,
primitiveType: Type primitiveType: Type
) : NumberLikeCompare(leftPrimitive, rightBoxed, primitiveType, KtTokens.EQEQ) { ) : PrimitiveToSomethingEquality(leftPrimitive, rightBoxed, primitiveType) {
private val primitiveType = leftPrimitive.type
private val boxedType = rightBoxed.type private val boxedType = rightBoxed.type
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) { override fun jumpIfCanCompareTopWithPrimitive(v: InstructionAdapter, label: Label) {
if (jumpIfFalse) { v.ifnonnull(label)
jumpIfFalse(v, jumpLabel)
}
else {
jumpIfTrue(v, jumpLabel)
}
} }
private fun jumpIfFalse(v: InstructionAdapter, jumpLabel: Label) { override fun coerceRightToPrimitive(v: InstructionAdapter) {
val notNullLabel = Label()
arg1.put(primitiveType, v)
arg2!!.put(boxedType, v)
AsmUtil.dup(v, boxedType)
v.ifnonnull(notNullLabel)
AsmUtil.pop(v, boxedType)
AsmUtil.pop(v, primitiveType)
v.goTo(jumpLabel)
v.mark(notNullLabel)
coerce(boxedType, primitiveType, v) coerce(boxedType, primitiveType, v)
v.visitJumpInsn(patchOpcode(opcode, v), jumpLabel)
}
private fun jumpIfTrue(v: InstructionAdapter, jumpLabel: Label) {
val notNullLabel = Label()
val endLabel = Label()
arg1.put(primitiveType, v)
arg2!!.put(boxedType, v)
AsmUtil.dup(v, boxedType)
v.ifnonnull(notNullLabel)
AsmUtil.pop(v, boxedType)
AsmUtil.pop(v, primitiveType)
v.goTo(endLabel)
v.mark(notNullLabel)
coerce(boxedType, primitiveType, v)
v.visitJumpInsn(patchOpcode(negatedOperations[opcode]!!, v), jumpLabel)
v.mark(endLabel)
} }
companion object { companion object {
@@ -333,59 +275,17 @@ class PrimitiveToObjectEquality private constructor(
leftPrimitive: StackValue, leftPrimitive: StackValue,
rightObject: StackValue, rightObject: StackValue,
primitiveType: Type primitiveType: Type
) : NumberLikeCompare(leftPrimitive, rightObject, primitiveType, KtTokens.EQEQ) { ) : PrimitiveToSomethingEquality(leftPrimitive, rightObject, primitiveType) {
private val primitiveType = leftPrimitive.type
private val objectType = rightObject.type
private val boxedType = AsmUtil.boxType(primitiveType) private val boxedType = AsmUtil.boxType(primitiveType)
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) { override fun jumpIfCanCompareTopWithPrimitive(v: InstructionAdapter, label: Label) {
if (jumpIfFalse) { v.instanceOf(boxedType)
jumpIfFalse(v, jumpLabel) v.ifne(label)
}
else {
jumpIfTrue(v, jumpLabel)
}
} }
private fun jumpIfFalse(v: InstructionAdapter, jumpLabel: Label) { override fun coerceRightToPrimitive(v: InstructionAdapter) {
val isBoxedLabel = Label() coerce(rightType, boxedType, v)
arg1.put(primitiveType, v)
arg2!!.put(objectType, v)
AsmUtil.dup(v, objectType)
v.instanceOf(boxedType)
v.ifne(isBoxedLabel)
AsmUtil.pop(v, objectType)
AsmUtil.pop(v, primitiveType)
v.goTo(jumpLabel)
v.mark(isBoxedLabel)
coerce(objectType, boxedType, v)
coerce(boxedType, primitiveType, v) coerce(boxedType, primitiveType, v)
v.visitJumpInsn(patchOpcode(opcode, v), jumpLabel)
}
private fun jumpIfTrue(v: InstructionAdapter, jumpLabel: Label) {
val isBoxedLabel = Label()
val endLabel = Label()
arg1.put(primitiveType, v)
arg2!!.put(objectType, v)
AsmUtil.dup(v, objectType)
v.instanceOf(boxedType)
v.ifne(isBoxedLabel)
AsmUtil.pop(v, objectType)
AsmUtil.pop(v, primitiveType)
v.goTo(endLabel)
v.mark(isBoxedLabel)
coerce(objectType, boxedType, v)
coerce(boxedType, primitiveType, v)
v.visitJumpInsn(patchOpcode(negatedOperations[opcode]!!, v), jumpLabel)
v.mark(endLabel)
} }
companion object { companion object {