From 1833a69c87d075445f7236c6418a259a45c07eef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Tue, 17 Sep 2019 17:05:59 +0200 Subject: [PATCH] JVM: Optimize inline class equality with nullable arguments --- .../kotlin/codegen/ExpressionCodegen.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 858b6bec5c0..d5ecf0a5959 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -3409,7 +3409,7 @@ public class ExpressionCodegen extends KtVisitor impleme if (!leftIsUnboxed || !rightIsUnboxed || !leftHasPrimitiveEquality || !rightHasPrimitiveEquality) { return genEqualsForInlineClasses( left, right, opToken, pregeneratedSubject, leftKotlinType, rightKotlinType, - leftType, rightType, leftIsUnboxed, rightIsUnboxed + leftType, rightType, leftIsInlineClass, leftIsUnboxed, rightIsUnboxed ); } } @@ -3502,6 +3502,7 @@ public class ExpressionCodegen extends KtVisitor impleme @NotNull KotlinType rightKotlinType, @NotNull Type leftType, @NotNull Type rightType, + boolean leftIsInlineClass, boolean leftIsUnboxed, boolean rightIsUnboxed ) { @@ -3514,7 +3515,9 @@ public class ExpressionCodegen extends KtVisitor impleme boolean flipComparison = opToken == KtTokens.EXCLEQ || opToken == KtTokens.EXCLEQEQEQ; // Don't call equals-impl0 if the class file version is too low to support it. - boolean useUnboxedEquals = leftIsUnboxed && JvmCodegenUtil.typeHasSpecializedInlineClassEquality(leftKotlinType, state); + boolean useUnboxedEquals = + (leftIsUnboxed || (leftIsInlineClass && rightIsUnboxed)) && + JvmCodegenUtil.typeHasSpecializedInlineClassEquality(leftKotlinType, state); leftValue.put(leftType, leftKotlinType, v); //noinspection SuspiciousNameCombination @@ -3571,12 +3574,18 @@ public class ExpressionCodegen extends KtVisitor impleme v.goTo(endLabel); v.visitLabel(nonNullLabel); } - String descriptor = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, leftType, leftType); + if (!leftIsUnboxed) { + AsmUtil.swap(v, topType, afterTopType); + KotlinType nonNullableLeftKotlinType = TypeUtils.makeNotNullable(leftKotlinType); + Type nonNullableLeftType = typeMapper.mapType(nonNullableLeftKotlinType); + StackValue.coerce(leftType, leftKotlinType, nonNullableLeftType, nonNullableLeftKotlinType, v); + afterTopType = nonNullableLeftType; + AsmUtil.swap(v, afterTopType, topType); + } + String descriptor = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, afterTopType, afterTopType); v.invokestatic(className, InlineClassDescriptorResolver.SPECIALIZED_EQUALS_NAME.asString(), descriptor, false); } else { - // equals-impl expects a non-nullable first argument, yet `left` may be unboxed even if - // it is nullable when it is a wrapper around a non-nullable reference type. - String descriptor = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, leftType, OBJECT_TYPE); + String descriptor = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, afterTopType, OBJECT_TYPE); v.invokestatic(className, "equals-impl", descriptor, false); } } else {