JVM: Generate equals-impl0 method for inline classes
This commit is contained in:
committed by
Alexander Udalov
parent
2c7da67600
commit
f53b28e8a3
@@ -861,6 +861,33 @@ public class AsmUtil {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static BranchedValue genTotalOrderEqualsForExpressionOnStack(
|
||||||
|
@NotNull StackValue left,
|
||||||
|
@NotNull StackValue right,
|
||||||
|
@NotNull Type asmType
|
||||||
|
) {
|
||||||
|
return new BranchedValue(left, right, asmType, Opcodes.IFEQ) {
|
||||||
|
@Override
|
||||||
|
public void condJump(@NotNull Label jumpLabel, @NotNull InstructionAdapter iv, boolean jumpIfFalse) {
|
||||||
|
if (asmType.getSort() == Type.FLOAT) {
|
||||||
|
left.put(asmType, kotlinType, iv);
|
||||||
|
right.put(asmType, kotlinType, iv);
|
||||||
|
iv.invokestatic("java/lang/Float", "compare", "(FF)I", false);
|
||||||
|
iv.visitJumpInsn(patchOpcode(jumpIfFalse ? Opcodes.IFNE : Opcodes.IFEQ, iv), jumpLabel);
|
||||||
|
} else if (asmType.getSort() == Type.DOUBLE) {
|
||||||
|
left.put(asmType, kotlinType, iv);
|
||||||
|
right.put(asmType, kotlinType, iv);
|
||||||
|
iv.invokestatic("java/lang/Double", "compare", "(DD)I", false);
|
||||||
|
iv.visitJumpInsn(patchOpcode(jumpIfFalse ? Opcodes.IFNE : Opcodes.IFEQ, iv), jumpLabel);
|
||||||
|
} else {
|
||||||
|
StackValue value = genEqualsForExpressionsOnStack(KtTokens.EQEQ, left, right);
|
||||||
|
BranchedValue.Companion.condJump(value, jumpLabel, jumpIfFalse, iv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static StackValue genEqualsBoxedOnStack(@NotNull IElementType opToken) {
|
public static StackValue genEqualsBoxedOnStack(@NotNull IElementType opToken) {
|
||||||
return StackValue.operation(Type.BOOLEAN_TYPE, v -> genAreEqualCall(v, opToken));
|
return StackValue.operation(Type.BOOLEAN_TYPE, v -> genAreEqualCall(v, opToken));
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.codegen.AsmUtil.genTotalOrderEqualsForExpressionOnStack
|
||||||
import org.jetbrains.kotlin.codegen.context.ClassContext
|
import org.jetbrains.kotlin.codegen.context.ClassContext
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
@@ -17,6 +18,7 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.Synthetic
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.Synthetic
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
class ErasedInlineClassBodyCodegen(
|
class ErasedInlineClassBodyCodegen(
|
||||||
aClass: KtClass,
|
aClass: KtClass,
|
||||||
@@ -109,11 +111,17 @@ class ErasedInlineClassBodyCodegen(
|
|||||||
|
|
||||||
|
|
||||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||||
val iv = codegen.v
|
val firstIndex = codegen.frameMap.getIndex(specializedEqualsDescriptor.valueParameters[0])
|
||||||
iv.aconst(null)
|
val secondIndex = codegen.frameMap.getIndex(specializedEqualsDescriptor.valueParameters[1])
|
||||||
iv.athrow()
|
val asmType = signature.valueParameters[0].asmType
|
||||||
|
val left = StackValue.local(firstIndex, asmType)
|
||||||
|
val right = StackValue.local(secondIndex, asmType)
|
||||||
|
genTotalOrderEqualsForExpressionOnStack(left, right, asmType).put(Type.BOOLEAN_TYPE, codegen.v)
|
||||||
|
codegen.v.areturn(Type.BOOLEAN_TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun skipNotNullAssertionsForParameters(): Boolean = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-19
@@ -251,25 +251,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
|||||||
return Unit.INSTANCE;
|
return Unit.INSTANCE;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (asmType.getSort() == Type.FLOAT) {
|
genTotalOrderEqualsForExpressionOnStack(thisPropertyValue, otherPropertyValue, asmType).condJump(ne, iv, true);
|
||||||
thisPropertyValue.put(asmType, kotlinType, iv);
|
|
||||||
otherPropertyValue.put(asmType, kotlinType, iv);
|
|
||||||
iv.invokestatic("java/lang/Float", "compare", "(FF)I", false);
|
|
||||||
iv.ifne(ne);
|
|
||||||
}
|
|
||||||
else if (asmType.getSort() == Type.DOUBLE) {
|
|
||||||
thisPropertyValue.put(asmType, kotlinType, iv);
|
|
||||||
otherPropertyValue.put(asmType, kotlinType, iv);
|
|
||||||
iv.invokestatic("java/lang/Double", "compare", "(DD)I", false);
|
|
||||||
iv.ifne(ne);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
StackValue value = genEqualsForExpressionsOnStack(
|
|
||||||
KtTokens.EQEQ, thisPropertyValue, otherPropertyValue
|
|
||||||
);
|
|
||||||
value.put(Type.BOOLEAN_TYPE, iv);
|
|
||||||
iv.ifeq(ne);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iv.mark(eq);
|
iv.mark(eq);
|
||||||
|
|||||||
+3
-7
@@ -15,11 +15,7 @@ fun box(): String {
|
|||||||
Simple::class.java.getDeclaredMethod(name, String::class.java, String::class.java)
|
Simple::class.java.getDeclaredMethod(name, String::class.java, String::class.java)
|
||||||
?: return "$name not found"
|
?: return "$name not found"
|
||||||
|
|
||||||
val result = try {
|
if (specializedEquals.invoke(null, "a", "b") as Boolean)
|
||||||
specializedEquals.invoke(null, "a", "b")
|
return "Fail"
|
||||||
} catch (e: InvocationTargetException) {
|
return "OK"
|
||||||
return if (e.targetException is NullPointerException) "OK" else "${e.targetException}"
|
|
||||||
}
|
|
||||||
|
|
||||||
return if (result == false) "OK" else "Fail"
|
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
inline class AsNonNullPrimitive(val i: Int)
|
inline class AsNonNullPrimitive(val i: Int)
|
||||||
inline class AsNonNullReference(val s: String)
|
inline class AsNonNullReference(val s: String)
|
||||||
// ^ JVM: 5 assertions (constructor, box method, erased constructor, 2 assertions in equals--impl)
|
// ^ JVM: 3 assertions (constructor, box method, erased constructor)
|
||||||
// JVM IR: 1 assertion (erased constructor)
|
// JVM IR: 1 assertion (erased constructor)
|
||||||
|
|
||||||
fun nonNullPrimitive(a: AsNonNullPrimitive) {}
|
fun nonNullPrimitive(a: AsNonNullPrimitive) {}
|
||||||
@@ -14,7 +14,7 @@ fun asNullablePrimitive(c: AsNonNullPrimitive?) {}
|
|||||||
fun asNullableReference(c: AsNonNullReference?) {}
|
fun asNullableReference(c: AsNonNullReference?) {}
|
||||||
|
|
||||||
// JVM_TEMPLATES
|
// JVM_TEMPLATES
|
||||||
// 8 checkParameterIsNotNull
|
// 6 checkParameterIsNotNull
|
||||||
// 0 checkNotNullParameter
|
// 0 checkNotNullParameter
|
||||||
|
|
||||||
// JVM_IR_TEMPLATES
|
// JVM_IR_TEMPLATES
|
||||||
|
|||||||
Reference in New Issue
Block a user