JVM_IR Spill stack on array constructor call
KT-42932
This commit is contained in:
+13
-9
@@ -33,7 +33,7 @@ class ArrayConstructorLowering(val context: CommonBackendContext) : IrElementTra
|
||||
}
|
||||
}
|
||||
|
||||
private class ArrayConstructorTransformer(
|
||||
open class ArrayConstructorTransformer(
|
||||
val context: CommonBackendContext,
|
||||
val container: IrSymbolOwner
|
||||
) : IrElementTransformerVoidWithContext() {
|
||||
@@ -73,11 +73,12 @@ private class ArrayConstructorTransformer(
|
||||
val invokable = expression.getValueArgument(1)!!.transform(this, null)
|
||||
val scope = (currentScope ?: createScope(container)).scope
|
||||
return context.createIrBuilder(scope.scopeOwnerSymbol).irBlock(expression.startOffset, expression.endOffset) {
|
||||
beforeArrayConstructorBody(this)
|
||||
|
||||
val index = createTmpVariable(irInt(0), isMutable = true)
|
||||
val sizeVar = createTmpVariable(size)
|
||||
val result = createTmpVariable(irCall(sizeConstructor, expression.type).apply {
|
||||
|
||||
copyTypeArgumentsFrom(expression)
|
||||
copyTypeArgumentsFrom(expression)
|
||||
putValueArgument(0, irGet(sizeVar))
|
||||
})
|
||||
|
||||
@@ -91,12 +92,9 @@ private class ArrayConstructorTransformer(
|
||||
}
|
||||
body = irBlock {
|
||||
val tempIndex = createTmpVariable(irGet(index))
|
||||
val value = lambda?.inline(parent, listOf(tempIndex))?.patchDeclarationParents(scope.getLocalDeclarationParent()) ?: irCallOp(
|
||||
invoke.symbol,
|
||||
invoke.returnType,
|
||||
irGet(invokableVar!!),
|
||||
irGet(tempIndex)
|
||||
)
|
||||
val value =
|
||||
lambda?.run { inline(parent, listOf(tempIndex)).patchDeclarationParents(scope.getLocalDeclarationParent()) }
|
||||
?: irCallOp(invoke.symbol, invoke.returnType, irGet(invokableVar!!), irGet(tempIndex))
|
||||
+irCall(result.type.getClass()!!.functions.single { it.name == OperatorNameConventions.SET }).apply {
|
||||
dispatchReceiver = irGet(result)
|
||||
putValueArgument(0, irGet(tempIndex))
|
||||
@@ -106,7 +104,13 @@ private class ArrayConstructorTransformer(
|
||||
+irSet(index.symbol, irCallOp(inc.symbol, index.type, irGet(index)))
|
||||
}
|
||||
}
|
||||
|
||||
afterArrayConstructorBody(this)
|
||||
|
||||
+irGet(result)
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun beforeArrayConstructorBody(builder: IrBlockBuilder) {}
|
||||
protected open fun afterArrayConstructorBody(builder: IrBlockBuilder) {}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ private val provisionalFunctionExpressionPhase = makeIrFilePhase<CommonBackendCo
|
||||
)
|
||||
|
||||
private val arrayConstructorPhase = makeIrFilePhase(
|
||||
::ArrayConstructorLowering,
|
||||
::JvmArrayConstructorLowering,
|
||||
name = "ArrayConstructor",
|
||||
description = "Transform `Array(size) { index -> value }` into a loop"
|
||||
)
|
||||
|
||||
@@ -865,6 +865,16 @@ class JvmSymbols(
|
||||
val runSuspendFunction: IrSimpleFunctionSymbol =
|
||||
kotlinCoroutinesJvmInternalRunSuspendKt.functionByName("runSuspend")
|
||||
|
||||
private val inlineMarkerClass: IrClassSymbol = createClass(
|
||||
JvmClassName.byInternalName("kotlin/jvm/internal/InlineMarker").fqNameForClassNameWithoutDollars
|
||||
) { irClass ->
|
||||
irClass.addFunction("beforeInlineCall", irBuiltIns.unitType, isStatic = true)
|
||||
irClass.addFunction("afterInlineCall", irBuiltIns.unitType, isStatic = true)
|
||||
}
|
||||
|
||||
val beforeInlineCall = inlineMarkerClass.functionByName("beforeInlineCall")
|
||||
val afterInlineCall = inlineMarkerClass.functionByName("afterInlineCall")
|
||||
|
||||
companion object {
|
||||
val FLEXIBLE_NULLABILITY_ANNOTATION_FQ_NAME =
|
||||
IrBuiltIns.KOTLIN_INTERNAL_IR_FQN.child(Name.identifier("FlexibleNullability"))
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.lower.ArrayConstructorTransformer
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.ir.builders.IrBlockBuilder
|
||||
import org.jetbrains.kotlin.ir.builders.irCall
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
class JvmArrayConstructorLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), BodyLoweringPass {
|
||||
|
||||
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
||||
irBody.transformChildrenVoid(JvmArrayConstructorTransformer(context, container as IrSymbolOwner))
|
||||
}
|
||||
}
|
||||
|
||||
class JvmArrayConstructorTransformer(
|
||||
private val jvmContext: JvmBackendContext,
|
||||
container: IrSymbolOwner
|
||||
) : ArrayConstructorTransformer(jvmContext, container) {
|
||||
|
||||
override fun beforeArrayConstructorBody(builder: IrBlockBuilder) {
|
||||
with(builder) {
|
||||
+irCall(jvmContext.ir.symbols.beforeInlineCall)
|
||||
}
|
||||
}
|
||||
|
||||
override fun afterArrayConstructorBody(builder: IrBlockBuilder) {
|
||||
with(builder) {
|
||||
+irCall(jvmContext.ir.symbols.afterInlineCall)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user