Remove duplicate parameter null checks in JvmStatic delegate methods.
Remove unnecessary non-null parameter checks inside static delegate methods created for @JvmStatic companion object methods. Allows function generation strategy decide if such checks need to be injected. #KT-7188 Fixed
This commit is contained in:
committed by
Dmitry Petrov
parent
9e82ab38f0
commit
52ccd67ec1
@@ -558,7 +558,7 @@ public class FunctionCodegen {
|
|||||||
mv.visitLabel(methodEntry);
|
mv.visitLabel(methodEntry);
|
||||||
context.setMethodStartLabel(methodEntry);
|
context.setMethodStartLabel(methodEntry);
|
||||||
|
|
||||||
if (!KotlinTypeMapper.isAccessor(functionDescriptor)) {
|
if (!strategy.skipNotNullAssertionsForParameters()) {
|
||||||
genNotNullAssertionsForParameters(new InstructionAdapter(mv), parentCodegen.state, functionDescriptor, frameMap);
|
genNotNullAssertionsForParameters(new InstructionAdapter(mv), parentCodegen.state, functionDescriptor, frameMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1383,6 +1383,11 @@ public class FunctionCodegen {
|
|||||||
|
|
||||||
iv.areturn(delegateMethod.getReturnType());
|
iv.areturn(delegateMethod.getReturnType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean skipNotNullAssertionsForParameters() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ public abstract class FunctionGenerationStrategy {
|
|||||||
@NotNull MemberCodegen<?> parentCodegen
|
@NotNull MemberCodegen<?> parentCodegen
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public abstract boolean skipNotNullAssertionsForParameters();
|
||||||
|
|
||||||
public MethodVisitor wrapMethodVisitor(@NotNull MethodVisitor mv, int access, @NotNull String name, @NotNull String desc) {
|
public MethodVisitor wrapMethodVisitor(@NotNull MethodVisitor mv, int access, @NotNull String name, @NotNull String desc) {
|
||||||
return mv;
|
return mv;
|
||||||
}
|
}
|
||||||
@@ -76,6 +78,12 @@ public abstract class FunctionGenerationStrategy {
|
|||||||
doGenerateBody(codegen, signature);
|
doGenerateBody(codegen, signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean skipNotNullAssertionsForParameters() {
|
||||||
|
// Assume the strategy injects non-null checks for parameters by default
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature);
|
public abstract void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -671,6 +671,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
iv.areturn(componentType);
|
iv.areturn(componentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean skipNotNullAssertionsForParameters() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,6 +724,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.areturn(thisDescriptorType);
|
iv.areturn(thisDescriptorType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean skipNotNullAssertionsForParameters() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void pushCapturedFieldsOnStack(InstructionAdapter iv, MutableClosure closure) {
|
private void pushCapturedFieldsOnStack(InstructionAdapter iv, MutableClosure closure) {
|
||||||
ClassDescriptor captureThis = closure.getCaptureThis();
|
ClassDescriptor captureThis = closure.getCaptureThis();
|
||||||
if (captureThis != null) {
|
if (captureThis != null) {
|
||||||
|
|||||||
+2
@@ -44,6 +44,8 @@ class JvmStaticInCompanionObjectGenerator(
|
|||||||
Synthetic(originElement, staticFunctionDescriptor),
|
Synthetic(originElement, staticFunctionDescriptor),
|
||||||
staticFunctionDescriptor,
|
staticFunctionDescriptor,
|
||||||
object : FunctionGenerationStrategy.CodegenBased(state) {
|
object : FunctionGenerationStrategy.CodegenBased(state) {
|
||||||
|
override fun skipNotNullAssertionsForParameters(): Boolean = true
|
||||||
|
|
||||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||||
val iv = codegen.v
|
val iv = codegen.v
|
||||||
val classDescriptor = descriptor.containingDeclaration as ClassDescriptor
|
val classDescriptor = descriptor.containingDeclaration as ClassDescriptor
|
||||||
|
|||||||
@@ -719,6 +719,11 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
|||||||
functionCodegen.generateMethod(
|
functionCodegen.generateMethod(
|
||||||
Synthetic(null, original), accessor,
|
Synthetic(null, original), accessor,
|
||||||
new FunctionGenerationStrategy.CodegenBased(state) {
|
new FunctionGenerationStrategy.CodegenBased(state) {
|
||||||
|
@Override
|
||||||
|
public boolean skipNotNullAssertionsForParameters() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||||
markLineNumberForElement(element.getPsiOrParent(), codegen.v);
|
markLineNumberForElement(element.getPsiOrParent(), codegen.v);
|
||||||
@@ -779,6 +784,11 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
|||||||
|
|
||||||
iv.areturn(signature.getReturnType());
|
iv.areturn(signature.getReturnType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean skipNotNullAssertionsForParameters() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (accessor.isWithSyntheticGetterAccessor()) {
|
if (accessor.isWithSyntheticGetterAccessor()) {
|
||||||
|
|||||||
@@ -312,6 +312,10 @@ class MultifileClassCodegenImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
object DelegateToCompiledMemberGenerationStrategy : FunctionGenerationStrategy() {
|
object DelegateToCompiledMemberGenerationStrategy : FunctionGenerationStrategy() {
|
||||||
|
override fun skipNotNullAssertionsForParameters(): kotlin.Boolean {
|
||||||
|
throw IllegalStateException("shouldn't be called")
|
||||||
|
}
|
||||||
|
|
||||||
override fun generateBody(mv: MethodVisitor, frameMap: FrameMap, signature: JvmMethodSignature, context: MethodContext, parentCodegen: MemberCodegen<*>) {
|
override fun generateBody(mv: MethodVisitor, frameMap: FrameMap, signature: JvmMethodSignature, context: MethodContext, parentCodegen: MemberCodegen<*>) {
|
||||||
throw IllegalStateException("shouldn't be called")
|
throw IllegalStateException("shouldn't be called")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -531,6 +531,10 @@ class CoroutineCodegenForNamedFunction private constructor(
|
|||||||
private const val COROUTINE_LAMBDA_PARAMETER_PREFIX = "p$"
|
private const val COROUTINE_LAMBDA_PARAMETER_PREFIX = "p$"
|
||||||
|
|
||||||
private object FailingFunctionGenerationStrategy : FunctionGenerationStrategy() {
|
private object FailingFunctionGenerationStrategy : FunctionGenerationStrategy() {
|
||||||
|
override fun skipNotNullAssertionsForParameters(): kotlin.Boolean {
|
||||||
|
error("This functions must not be called")
|
||||||
|
}
|
||||||
|
|
||||||
override fun generateBody(
|
override fun generateBody(
|
||||||
mv: MethodVisitor,
|
mv: MethodVisitor,
|
||||||
frameMap: FrameMap,
|
frameMap: FrameMap,
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
|
// FILE: Dummy.kt
|
||||||
|
// Empty body to trigger multifile test mode
|
||||||
|
|
||||||
|
// FILE: Test.kt
|
||||||
|
class TestMethod {
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
fun test(s0: String, s1: String?) = s0 + (s1 ?: "null")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestMethodOverloads {
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
@JvmOverloads
|
||||||
|
fun test(s0: String = "s0", s1: String = "s1", s2: String = "s2") = s0 + s1 + s2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestProperty {
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
var prop: String = "Blah"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestAccessor {
|
||||||
|
companion object {
|
||||||
|
var prop: String = "Blah" @JvmStatic set
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @TestMethod.class:
|
||||||
|
// 0 INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull \(Ljava/lang/Object;Ljava/lang/String;\)V
|
||||||
|
|
||||||
|
// @TestMethodOverloads.class:
|
||||||
|
// 0 INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull \(Ljava/lang/Object;Ljava/lang/String;\)V
|
||||||
|
|
||||||
|
// @TestProperty.class:
|
||||||
|
// 0 INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull \(Ljava/lang/Object;Ljava/lang/String;\)V
|
||||||
|
|
||||||
|
// @TestAccessor.class:
|
||||||
|
// 0 INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull \(Ljava/lang/Object;Ljava/lang/String;\)V
|
||||||
@@ -282,6 +282,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt7188.kt")
|
||||||
|
public void testKt7188() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/kt7188.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt7769.kt")
|
@TestMetadata("kt7769.kt")
|
||||||
public void testKt7769() throws Exception {
|
public void testKt7769() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/kt7769.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/kt7769.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user