[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 <Aleksander.Kuznetsov@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
df0e4e0b53
commit
ece7dce2ae
+1
-1
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user