JVM: remove TypedNullValue, hack interpreter instead

This commit is contained in:
pyos
2022-05-10 16:38:39 +02:00
committed by teamcity
parent 513ef575ce
commit 0fc676a20c
5 changed files with 13 additions and 39 deletions
@@ -669,7 +669,7 @@ class CoroutineTransformerMethodVisitor(
val value = frame.getLocal(slot)
if (value.type == null || !livenessFrame.isAlive(slot)) continue
if (value == StrictBasicValue.NULL_VALUE || value is TypedNullValue) {
if (value == StrictBasicValue.NULL_VALUE) {
referencesToSpill += slot to null
continue
}
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.codegen.coroutines
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.optimization.common.FastMethodAnalyzer
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
@@ -135,7 +134,7 @@ internal fun performSpilledVariableFieldTypesAnalysis(
for ((insn, type) in interpreter.needsToBeCoerced) {
methodNode.instructions.insert(insn, withInstructionAdapter { coerceInt(type, this) })
}
return FastMethodAnalyzer(thisName, methodNode, NullCheckcastAwareOptimizationBasicInterpreter()).analyze()
return FastMethodAnalyzer(thisName, methodNode, OptimizationBasicInterpreter()).analyze()
}
private fun coerceInt(to: Type, v: InstructionAdapter) {
@@ -159,24 +158,3 @@ private fun Type.isIntLike(): Boolean = when (sort) {
Type.BOOLEAN, Type.BYTE, Type.CHAR, Type.SHORT -> true
else -> false
}
// Represents [ACONST_NULL, CHECKCAST Type] sequence result.
internal class TypedNullValue(type: Type) : StrictBasicValue(type)
// Preserves nulls through CHECKCASTS.
private class NullCheckcastAwareOptimizationBasicInterpreter : OptimizationBasicInterpreter() {
override fun unaryOperation(insn: AbstractInsnNode, value: BasicValue?): BasicValue? {
if (insn.opcode == Opcodes.CHECKCAST && (value == StrictBasicValue.NULL_VALUE || value is TypedNullValue)) {
return TypedNullValue(Type.getObjectType((insn as TypeInsnNode).desc))
}
return super.unaryOperation(insn, value)
}
override fun merge(v: BasicValue, w: BasicValue): BasicValue =
when {
v is TypedNullValue && w is TypedNullValue -> if (v.type == w.type) v else StrictBasicValue.NULL_VALUE
v is TypedNullValue -> super.merge(StrictBasicValue.NULL_VALUE, w)
w is TypedNullValue -> super.merge(v, StrictBasicValue.NULL_VALUE)
else -> super.merge(v, w)
}
}
@@ -204,7 +204,7 @@ public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implem
case DREM:
return StrictBasicValue.DOUBLE_VALUE;
case AALOAD:
return StrictBasicValue.REFERENCE_VALUE;
return StrictBasicValue.NULL_VALUE;
case LCMP:
case FCMPL:
case FCMPG:
@@ -331,6 +331,9 @@ public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implem
case ATHROW:
return null;
case CHECKCAST:
if (value == StrictBasicValue.NULL_VALUE) {
return StrictBasicValue.NULL_VALUE;
}
desc = ((TypeInsnNode) insn).desc;
return newValue(Type.getObjectType(desc));
case INSTANCEOF:
@@ -68,7 +68,12 @@ open class StrictBasicValue(type: Type?) : BasicValue(type) {
override fun hashCode() = (type?.hashCode() ?: 0)
override fun toString(): String {
if (this === UNINITIALIZED_VALUE) return "."
return super.toString()
val inner = when {
this === REFERENCE_VALUE -> "R"
this === NULL_VALUE -> "null"
this === UNINITIALIZED_VALUE -> "."
else -> super.toString()
}
return "${this::class.java.simpleName}($inner)"
}
}