From ece7dce2aea5fd48c976450892a1ec425abdd64d Mon Sep 17 00:00:00 2001 From: Alexander Kuznetsov Date: Mon, 17 Jul 2023 15:21:05 +0000 Subject: [PATCH] [debugger] FragmentLocalFunctionPatchLowering: remove pointless visiting `FragmentLocalFunctionPatchLowering.visitSimpleFunction` uses a transformer with an overridden `visitCall`. Inside it visits every nested call recursively in two places: in the beginning (1, line 59), and via super method if the current call doesn't refer to a local function (2, line 64). It leads to a combinatorial explosion: if there are N nested calls in one expression, then the number of `visitCall` invocations will be `pow(2, N)`. Thus, it will take forever to compile certain expressions. A perfect example of a long nested call is string interpolation: string templates are being compiled to a chain of `StringBuilder::append` calls. Here's why IDEA-325225 happens -- the code in the issue has large string templates, and the resulting `StringBuilder::append` chains may contain up to 30 links, making for around 1 billion `visitCall` invocations. However, the visiting (2) is obsolete. First, the visiting (1) will process all the children of an expression, replacing them with the right local function calls, if necessary, recursively, up the stack. Second, the expression itself will be transformed, if necessary, in that same method, after all its children are processed. That means we can get rid of one visiting and avoid the combinatorial explosion, yet all the local function calls will still be correctly processed. Fixes IDEA-325225, contributes to IDEA-325146 Merge-request: KT-MR-11104 Merged-by: Alexander Kuznetsov --- .../backend/jvm/lower/FragmentLocalFunctionPatchLowering.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FragmentLocalFunctionPatchLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FragmentLocalFunctionPatchLowering.kt index 5d2d8af2f78..c82e0be4fb1 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FragmentLocalFunctionPatchLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FragmentLocalFunctionPatchLowering.kt @@ -61,7 +61,7 @@ internal class FragmentLocalFunctionPatchLowering( is IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER -> context.mapping.defaultArgumentsOriginalFunction[expression.symbol.owner] else -> expression.symbol.owner } - val localsData = localDeclarationsData[localDeclarationsDataKey] ?: return super.visitCall(expression) + val localsData = localDeclarationsData[localDeclarationsDataKey] ?: return expression val remappedTarget: LocalDeclarationsLowering.LocalFunctionContext = localsData.localContext val irBuilder = context.createJvmIrBuilder(declaration.symbol)