JVM IR: Avoid unnecessary CHECKCASTs in enum classes
This commit is contained in:
committed by
max-kammerer
parent
cb3a4727cf
commit
b6b8dd1eab
+11
-1
@@ -539,7 +539,17 @@ class ExpressionCodegen(
|
||||
ownerType.internalName
|
||||
} ?: typeMapper.mapClass(callee.parentAsClass).internalName
|
||||
return if (expression is IrSetField) {
|
||||
expression.value.accept(this, data).materializeAt(fieldType, callee.type)
|
||||
val value = expression.value.accept(this, data)
|
||||
|
||||
// We only initialize enum entries with a subtype of `fieldType` and can avoid the CHECKCAST.
|
||||
// This is important for some tools which analyze bytecode for enum classes by looking at the
|
||||
// initializer of the $VALUES field.
|
||||
if (callee.origin == IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRY) {
|
||||
value.materialize()
|
||||
} else {
|
||||
value.materializeAt(fieldType, callee.type)
|
||||
}
|
||||
|
||||
when {
|
||||
isStatic -> mv.putstatic(ownerName, fieldName, fieldType.descriptor)
|
||||
else -> mv.putfield(ownerName, fieldName, fieldType.descriptor)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
enum class Foo {
|
||||
A, B, C { override fun result() = "OK" };
|
||||
open fun result() = "Fail"
|
||||
}
|
||||
|
||||
// JVM_TEMPLATES:
|
||||
// There are two CHECKCASTs, one in Foo.valueOf and one in Foo.values
|
||||
// 2 CHECKCAST
|
||||
|
||||
// JVM_IR_TEMPLATES:
|
||||
// There should be only one CHECKCAST in Foo.valueOf
|
||||
// 1 CHECKCAST
|
||||
@@ -1855,6 +1855,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/enum"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("enumCheckcasts.kt")
|
||||
public void testEnumCheckcasts() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/enum/enumCheckcasts.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt18731.kt")
|
||||
public void testKt18731() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/enum/kt18731.kt");
|
||||
|
||||
+5
@@ -1810,6 +1810,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/enum"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("enumCheckcasts.kt")
|
||||
public void testEnumCheckcasts() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/enum/enumCheckcasts.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt18731.kt")
|
||||
public void testKt18731() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/enum/kt18731.kt");
|
||||
|
||||
Reference in New Issue
Block a user