JVM: Optimize inline class equality with nullable arguments
This commit is contained in:
committed by
Alexander Udalov
parent
eda4953cb3
commit
1833a69c87
@@ -3409,7 +3409,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
if (!leftIsUnboxed || !rightIsUnboxed || !leftHasPrimitiveEquality || !rightHasPrimitiveEquality) {
|
if (!leftIsUnboxed || !rightIsUnboxed || !leftHasPrimitiveEquality || !rightHasPrimitiveEquality) {
|
||||||
return genEqualsForInlineClasses(
|
return genEqualsForInlineClasses(
|
||||||
left, right, opToken, pregeneratedSubject, leftKotlinType, rightKotlinType,
|
left, right, opToken, pregeneratedSubject, leftKotlinType, rightKotlinType,
|
||||||
leftType, rightType, leftIsUnboxed, rightIsUnboxed
|
leftType, rightType, leftIsInlineClass, leftIsUnboxed, rightIsUnboxed
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3502,6 +3502,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
@NotNull KotlinType rightKotlinType,
|
@NotNull KotlinType rightKotlinType,
|
||||||
@NotNull Type leftType,
|
@NotNull Type leftType,
|
||||||
@NotNull Type rightType,
|
@NotNull Type rightType,
|
||||||
|
boolean leftIsInlineClass,
|
||||||
boolean leftIsUnboxed,
|
boolean leftIsUnboxed,
|
||||||
boolean rightIsUnboxed
|
boolean rightIsUnboxed
|
||||||
) {
|
) {
|
||||||
@@ -3514,7 +3515,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
boolean flipComparison = opToken == KtTokens.EXCLEQ || opToken == KtTokens.EXCLEQEQEQ;
|
boolean flipComparison = opToken == KtTokens.EXCLEQ || opToken == KtTokens.EXCLEQEQEQ;
|
||||||
|
|
||||||
// Don't call equals-impl0 if the class file version is too low to support it.
|
// 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);
|
leftValue.put(leftType, leftKotlinType, v);
|
||||||
//noinspection SuspiciousNameCombination
|
//noinspection SuspiciousNameCombination
|
||||||
@@ -3571,12 +3574,18 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
v.goTo(endLabel);
|
v.goTo(endLabel);
|
||||||
v.visitLabel(nonNullLabel);
|
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);
|
v.invokestatic(className, InlineClassDescriptorResolver.SPECIALIZED_EQUALS_NAME.asString(), descriptor, false);
|
||||||
} else {
|
} else {
|
||||||
// equals-impl expects a non-nullable first argument, yet `left` may be unboxed even if
|
String descriptor = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, afterTopType, OBJECT_TYPE);
|
||||||
// it is nullable when it is a wrapper around a non-nullable reference type.
|
|
||||||
String descriptor = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, leftType, OBJECT_TYPE);
|
|
||||||
v.invokestatic(className, "equals-impl", descriptor, false);
|
v.invokestatic(className, "equals-impl", descriptor, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user