diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index efcb71785ff..4abe9b4cc93 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -516,7 +516,7 @@ public class FunctionCodegen { // If the function doesn't have a physical declaration among super-functions, it's a SAM adapter or alike and doesn't need bridges if (CallResolverUtilKt.isOrOverridesSynthesized(descriptor)) return; - boolean isSpecial = SpecialBuiltinMembers.doesOverrideBuiltinWithDifferentJvmName(descriptor); + boolean isSpecial = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(descriptor) != null; Set> bridgesToGenerate; if (!isSpecial) { @@ -560,7 +560,7 @@ public class FunctionCodegen { } if (!descriptor.getKind().isReal() && isAbstractMethod(descriptor, OwnerKind.IMPLEMENTATION)) { - CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmName(descriptor); + CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(descriptor); assert overridden != null; Method method = typeMapper.mapSignature(descriptor).getAsmMethod(); @@ -852,6 +852,8 @@ public class FunctionCodegen { assert descriptor.getValueParameters().size() == 1 : "Should be descriptor with one value parameter, but found: " + descriptor; + if (bridge.getArgumentTypes()[0].getSort() != Type.OBJECT) return; + iv.load(1, OBJECT_TYPE); JetType jetType = descriptor.getValueParameters().get(0).getType(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/builtinSpecialBridges.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/builtinSpecialBridges.kt index 2e82070fbbb..ada93d726b6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/builtinSpecialBridges.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/builtinSpecialBridges.kt @@ -18,8 +18,8 @@ package org.jetbrains.kotlin.codegen import org.jetbrains.kotlin.backend.common.bridges.* import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.load.java.getOverriddenBuiltinWithDifferentJvmName import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor +import org.jetbrains.kotlin.load.java.getOverriddenBuiltinWithDifferentJvmDescriptor import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure @@ -41,16 +41,18 @@ object BuiltinSpecialBridgesUtil { val functionHandle = DescriptorBasedFunctionHandle(function) val fake = !functionHandle.isDeclaration - val overriddenBuiltin = function.getOverriddenBuiltinWithDifferentJvmName()!! + val overriddenBuiltin = function.getOverriddenBuiltinWithDifferentJvmDescriptor()!! val reachableDeclarations = findAllReachableDeclarations(function) - val needGenerateSpecialBridge = needGenerateSpecialBridge(function, reachableDeclarations, overriddenBuiltin) // e.g. `getSize()I` val methodItself = signatureByDescriptor(function) // e.g. `size()I` val overriddenBuiltinSignature = signatureByDescriptor(overriddenBuiltin) + val needGenerateSpecialBridge = needGenerateSpecialBridge(function, reachableDeclarations, overriddenBuiltin) + && methodItself != overriddenBuiltinSignature + val specialBridge = if (needGenerateSpecialBridge) BridgeForBuiltinSpecial(overriddenBuiltinSignature, methodItself, isSpecial = true) else null diff --git a/compiler/testData/codegen/bytecodeListing/specialBridges/contains.txt b/compiler/testData/codegen/bytecodeListing/specialBridges/contains.txt index e8bbeb837e9..b2ec39aa68e 100644 --- a/compiler/testData/codegen/bytecodeListing/specialBridges/contains.txt +++ b/compiler/testData/codegen/bytecodeListing/specialBridges/contains.txt @@ -3,6 +3,7 @@ public method contains(p0: java.lang.Object): boolean public method containsAll(@org.jetbrains.annotations.NotNull p0: java.util.Collection): boolean public abstract method getSize(): int + public abstract method remove(p0: java.lang.Object): boolean public final method size(): int public method toArray(): java.lang.Object[] public method toArray(p0: java.lang.Object[]): java.lang.Object[] @@ -14,6 +15,8 @@ public final method contains(p0: java.lang.Object): boolean public method containsAll(@org.jetbrains.annotations.NotNull p0: java.util.Collection): boolean public abstract method getSize(): int + public final method remove(p0: java.lang.Object): boolean + public abstract method remove(p0: java.lang.String): boolean public final method size(): int public method toArray(): java.lang.Object[] public method toArray(p0: java.lang.Object[]): java.lang.Object[] @@ -21,8 +24,12 @@ @kotlin.jvm.internal.KotlinClass A3 { public method (): void + public synthetic method contains(p0: java.lang.Object): boolean public abstract method getSize(): int + public synthetic method indexOf(p0: java.lang.Object): int + public synthetic method lastIndexOf(p0: java.lang.Object): int public final method remove(p0: int): java.lang.Object + public synthetic method remove(p0: java.lang.Object): boolean public synthetic method removeAt(p0: int): java.lang.Object public final method size(): int } @@ -32,15 +39,26 @@ public method contains(p0: java.lang.Object): boolean public method containsAll(@org.jetbrains.annotations.NotNull p0: java.util.Collection): boolean public abstract method getSize(): int + public synthetic method indexOf(p0: java.lang.Object): int + public synthetic method lastIndexOf(p0: java.lang.Object): int public final method remove(p0: int): java.lang.Object + public synthetic method remove(p0: java.lang.Object): boolean public synthetic method removeAt(p0: int): java.lang.Object public final method size(): int } @kotlin.jvm.internal.KotlinClass A5 { public method (): void + public final method contains(p0: java.lang.Object): boolean + public synthetic method contains(p0: java.lang.String): boolean public abstract method getSize(): int + public final method indexOf(p0: java.lang.Object): int + public synthetic method indexOf(p0: java.lang.String): int + public final method lastIndexOf(p0: java.lang.Object): int + public synthetic method lastIndexOf(p0: java.lang.String): int public final method remove(p0: int): java.lang.String + public final method remove(p0: java.lang.Object): boolean + public synthetic method remove(p0: java.lang.String): boolean public synthetic method removeAt(p0: int): java.lang.String public final method size(): int } @@ -51,7 +69,13 @@ public final method contains(p0: java.lang.Object): boolean public method containsAll(@org.jetbrains.annotations.NotNull p0: java.util.Collection): boolean public abstract method getSize(): int + public final method indexOf(p0: java.lang.Object): int + public synthetic method indexOf(p0: java.lang.String): int + public final method lastIndexOf(p0: java.lang.Object): int + public synthetic method lastIndexOf(p0: java.lang.String): int public final method remove(p0: int): java.lang.String + public final method remove(p0: java.lang.Object): boolean + public synthetic method remove(p0: java.lang.String): boolean public synthetic method removeAt(p0: int): java.lang.String public final method size(): int } @@ -61,6 +85,8 @@ public method contains(p0: int): boolean public final method contains(p0: java.lang.Object): boolean public abstract method getSize(): int + public abstract method remove(p0: java.lang.Integer): boolean + public final method remove(p0: java.lang.Object): boolean public final method size(): int public method toArray(): java.lang.Object[] public method toArray(p0: java.lang.Object[]): java.lang.Object[] @@ -70,6 +96,7 @@ public method (): void public method contains(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean public abstract method getSize(): int + public abstract method remove(p0: java.lang.Object): boolean public final method size(): int public method toArray(): java.lang.Object[] public method toArray(p0: java.lang.Object[]): java.lang.Object[] diff --git a/compiler/testData/codegen/bytecodeText/builtinFunctions/contains.kt b/compiler/testData/codegen/bytecodeText/builtinFunctions/contains.kt index 8848e878fdb..d891d179dbe 100644 --- a/compiler/testData/codegen/bytecodeText/builtinFunctions/contains.kt +++ b/compiler/testData/codegen/bytecodeText/builtinFunctions/contains.kt @@ -101,7 +101,7 @@ fun foo( // 0 signature \(TW;\)Z // 0 signature \(TR;\)Z // 6 signature \(Ljava/util/Collection<\+Ljava/lang/Object;>;\)Z -// 3 public final bridge contains\(Ljava/lang/Object;\)Z +// 4 public final bridge contains\(Ljava/lang/Object;\)Z // 4 INVOKEVIRTUAL A[0-9]\.contains \(Ljava/lang/String;\)Z // 4 INVOKEVIRTUAL A[0-9]\.contains \(Ljava/lang/Object;\)Z // 2 INVOKEVIRTUAL A7\.contains \(I\)Z diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/specialBuiltinMembers.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/specialBuiltinMembers.kt index 2b8331b454a..3eebe7d1828 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/specialBuiltinMembers.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/specialBuiltinMembers.kt @@ -29,6 +29,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.addToStdlib.check import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties.getBuiltinSpecialPropertyGetterName +import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.sameAsBuiltinMethodWithErasedValueParameters +import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe object BuiltinSpecialProperties { @@ -47,7 +49,7 @@ object BuiltinSpecialProperties { PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP.getInversedShortNamesMap() private val FQ_NAMES = PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP.keySet() - private val SHORT_NAMES = FQ_NAMES.map { it.shortName() }.toSet() + internal val SHORT_NAMES = FQ_NAMES.map { it.shortName() }.toSet() fun hasBuiltinSpecialPropertyFqName(callableMemberDescriptor: CallableMemberDescriptor): Boolean { if (callableMemberDescriptor.name !in SHORT_NAMES) return false @@ -183,6 +185,18 @@ fun T.getOverriddenBuiltinWithDifferentJvmName(): fun CallableMemberDescriptor.doesOverrideBuiltinWithDifferentJvmName(): Boolean = getOverriddenBuiltinWithDifferentJvmName() != null +@Suppress("UNCHECKED_CAST") +fun T.getOverriddenBuiltinWithDifferentJvmDescriptor(): T? { + getOverriddenBuiltinWithDifferentJvmName()?.let { return it } + + if (!name.sameAsBuiltinMethodWithErasedValueParameters) return null + + return firstOverridden { + it.isFromBuiltins() + && it.getSpecialSignatureInfo() == BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo.GENERIC_PARAMETER + }?.original as T? +} + fun getJvmMethodNameIfSpecial(callableMemberDescriptor: CallableMemberDescriptor): String? { val builtinOverridden = getBuiltinOverriddenThatAffectsJvmName(callableMemberDescriptor)?.propertyIfAccessor ?: return null