Implement special cases for the hashCode intrinsic in JVM_IR

This commit is contained in:
Steven Schäfer
2019-05-07 17:27:10 +02:00
committed by max-kammerer
parent 1c3b895fc0
commit 570ee38256
5 changed files with 28 additions and 16 deletions
@@ -780,7 +780,7 @@ public class AsmUtil {
return typeMapper.mapToCallableMethod(toStringDescriptor, false, OwnerKind.ERASED_INLINE_CLASS);
}
static void genHashCode(MethodVisitor mv, InstructionAdapter iv, Type type, JvmTarget jvmTarget) {
public static void genHashCode(MethodVisitor mv, InstructionAdapter iv, Type type, JvmTarget jvmTarget) {
if (type.getSort() == Type.ARRAY) {
Type elementType = correctElementType(type);
if (elementType.getSort() == Type.OBJECT || elementType.getSort() == Type.ARRAY) {
@@ -16,24 +16,39 @@
package org.jetbrains.kotlin.backend.jvm.intrinsics
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.codegen.*
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
// TODO Implement hashCode on primitive types as a lowering.
object HashCode : IntrinsicMethod() {
override fun toCallable(expression: IrFunctionAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
return IrIntrinsicFunction.create(expression, signature, context, AsmTypes.OBJECT_TYPE) {
it.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo) = with(codegen) {
val receiver = expression.dispatchReceiver ?: error("No receiver for hashCode: ${expression.render()}")
val result = receiver.accept(this, data).materialized
val target = context.state.target
when {
irFunction.origin == IrDeclarationOrigin.GENERATED_INLINE_CLASS_MEMBER || irFunction.origin == IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER ->
AsmUtil.genHashCode(mv, mv, result.type, target)
target == JvmTarget.JVM_1_6 -> {
result.coerce(AsmUtil.boxType(result.type)).materialize()
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
}
else -> {
val boxedType = AsmUtil.boxType(result.type)
mv.visitMethodInsn(
Opcodes.INVOKESTATIC,
boxedType.internalName,
"hashCode",
Type.getMethodDescriptor(Type.INT_TYPE, result.type),
false
)
}
}
MaterialValue(codegen.mv, Type.INT_TYPE)
}
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
data class A(val a: Boolean)
fun box() : String {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// JVM_TARGET: 1.8
data class Hash(
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// JVM_TARGET: 1.8
fun box(): String {