diff --git a/compiler/backend.common.jvm/src/org/jetbrains/kotlin/codegen/signature/JvmSignatureWriter.java b/compiler/backend.common.jvm/src/org/jetbrains/kotlin/codegen/signature/JvmSignatureWriter.java index 0be043b0f48..01b63b68910 100644 --- a/compiler/backend.common.jvm/src/org/jetbrains/kotlin/codegen/signature/JvmSignatureWriter.java +++ b/compiler/backend.common.jvm/src/org/jetbrains/kotlin/codegen/signature/JvmSignatureWriter.java @@ -138,11 +138,11 @@ public class JvmSignatureWriter extends JvmDescriptorTypeWriter { @NotNull public JvmMethodGenericSignature makeJvmMethodSignature(@NotNull String name) { - List types = new ArrayList<>(kotlinParameterTypes.size()); - for (JvmMethodParameterSignature parameter : kotlinParameterTypes) { - types.add(parameter.getAsmType()); + Type[] types = new Type[kotlinParameterTypes.size()]; + for (int i = 0; i < kotlinParameterTypes.size(); i++) { + types[i] = kotlinParameterTypes.get(i).getAsmType(); } - Method asmMethod = new Method(name, jvmReturnType, types.toArray(new Type[types.size()])); + Method asmMethod = new Method(name, jvmReturnType, types); return new JvmMethodGenericSignature(asmMethod, kotlinParameterTypes, makeJavaGenericSignature()); } diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/UniqueLoopLabelsLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/UniqueLoopLabelsLowering.kt index b657053f439..c451601f161 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/UniqueLoopLabelsLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/UniqueLoopLabelsLowering.kt @@ -12,29 +12,40 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrDeclarationWithName import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.expressions.IrLoop -import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid +import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.name.Name internal val uniqueLoopLabelsPhase = makeIrFilePhase( - ::UniqueLoopLabelsLowering, + { _: JvmBackendContext -> UniqueLoopLabelsLowering() }, name = "UniqueLoopLabels", description = "Label all loops for non-local break/continue" ) -private class UniqueLoopLabelsLowering(val context: JvmBackendContext) : FileLoweringPass { +private class UniqueLoopLabelsLowering : FileLoweringPass { override fun lower(irFile: IrFile) { - irFile.accept(object : IrElementVisitor { + irFile.acceptVoid(object : IrElementVisitorVoid { // This counter is intentionally not local to every declaration because their names might clash. private var counter = 0 + private val stack = ArrayList() - override fun visitElement(element: IrElement, data: String) = - element.acceptChildren(this, if (element is IrDeclarationWithName) "$data${element.name}$" else data) + override fun visitElement(element: IrElement) { + if (element is IrDeclarationWithName) { + stack.add(element.name) + element.acceptChildrenVoid(this) + stack.removeLast() + } else { + element.acceptChildrenVoid(this) + } + } - override fun visitLoop(loop: IrLoop, data: String) { + override fun visitLoop(loop: IrLoop) { // Give all loops unique labels so that we can generate unambiguous instructions for non-local // `break`/`continue` statements. - loop.label = "$data${++counter}" - super.visitLoop(loop, data) + loop.label = stack.joinToString("$", postfix = (++counter).toString()) + super.visitLoop(loop) } - }, "") + }) } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/caches/BridgeLoweringCache.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/caches/BridgeLoweringCache.kt index 32cf484662f..6b541277a1b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/caches/BridgeLoweringCache.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/caches/BridgeLoweringCache.kt @@ -35,9 +35,12 @@ class BridgeLoweringCache(private val context: JvmBackendContext) { return true // Function name could be mangled by inline class rules val functionName = function.name.asString() - if (specialBridgeMethods.specialMethodNames.any { functionName.startsWith(it.asString() + "-") }) - return true - return false + return specialBridgeMethods.specialMethodNames.any { + // Optimized version of functionName.startsWith(it.asString() + "-") which is a hot spot + val specialMethodNameString = it.asString() + val specialMethodNameLength = specialMethodNameString.length + functionName.startsWith(specialMethodNameString) && functionName.length > specialMethodNameLength && functionName[specialMethodNameLength] == '-' + } } fun computeSpecialBridge(function: IrSimpleFunction): SpecialBridge? { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypePredicates.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypePredicates.kt index 660759ddd7a..c4c56241a3a 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypePredicates.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypePredicates.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.hasEqualFqName +import org.jetbrains.kotlin.ir.util.hasTopLevelEqualFqName import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.Name @@ -74,8 +75,7 @@ private fun IrType.isClassType(signature: IdSignature.CommonSignature, nullable: } private fun IrClass.hasFqNameEqualToSignature(signature: IdSignature.CommonSignature): Boolean = - name.asString() == signature.shortName && - hasEqualFqName(FqName("${signature.packageFqName}.${signature.declarationFqName}")) + name.asString() == signature.shortName && hasTopLevelEqualFqName(signature.packageFqName, signature.declarationFqName) fun IrClassifierSymbol.isClassWithFqName(fqName: FqNameUnsafe): Boolean = this is IrClassSymbol && classFqNameEquals(this, fqName) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/AdditionalIrUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/AdditionalIrUtils.kt index 57789763db9..e7e45a8ae1c 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/AdditionalIrUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/AdditionalIrUtils.kt @@ -146,9 +146,27 @@ fun IrDeclarationWithName.hasEqualFqName(fqName: FqName): Boolean = else -> false } +fun IrDeclarationWithName.hasTopLevelEqualFqName(packageName: String, declarationName: String): Boolean = + symbol.hasTopLevelEqualFqName(packageName, declarationName) || name.asString() == declarationName && when (val parent = parent) { + is IrPackageFragment -> parent.packageFqName.asString() == packageName + else -> false + } + fun IrSymbol.hasEqualFqName(fqName: FqName): Boolean { return this is IrClassPublicSymbolImpl && with(signature as? IdSignature.CommonSignature ?: return false) { - FqName("$packageFqName.$declarationFqName") == fqName + // optimized version of FqName("$packageFqName.$declarationFqName") == fqName + val fqNameAsString = fqName.asString() + fqNameAsString.length == packageFqName.length + 1 + declarationFqName.length && + fqNameAsString[packageFqName.length] == '.' && + fqNameAsString.startsWith(packageFqName) && + fqNameAsString.endsWith(declarationFqName) + } +} + +private fun IrSymbol.hasTopLevelEqualFqName(packageName: String, declarationName: String): Boolean { + return this is IrClassPublicSymbolImpl && with(signature as? IdSignature.CommonSignature ?: return false) { + // optimized version of FqName("$packageFqName.$declarationFqName") == fqName + packageFqName == packageName && declarationFqName == declarationName } }