Compare commits

...

4 Commits

Author SHA1 Message Date
Dmitry Petrov
4dc65c6a3e JVM_IR KT-45103 optimize direct invoke for lambdas and callable refs 2021-04-26 17:17:25 +03:00
Dmitry Petrov
05e642cacf JVM_IR KT-36646 fuze primitive equality with safe call 2021-04-26 13:10:32 +03:00
Dmitry Petrov
f830786b20 JVM_IR update test for KT-36637 2021-04-26 13:10:31 +03:00
Dmitry Petrov
22c5b3a990 JVM_IR use static 'hashCode' for boxed primitives on JVM 1.8+ 2021-04-26 13:10:31 +03:00
42 changed files with 966 additions and 104 deletions

View File

@@ -39,7 +39,7 @@ class RedundantBoxingMethodTransformer(private val generationState: GenerationSt
override fun transform(internalClassName: String, node: MethodNode) {
val interpreter = RedundantBoxingInterpreter(node.instructions, generationState)
val frames = MethodTransformer.analyze(internalClassName, node, interpreter)
val frames = analyze(internalClassName, node, interpreter)
interpretPopInstructionsForBoxedValues(interpreter, node, frames)
@@ -168,7 +168,8 @@ class RedundantBoxingMethodTransformer(private val generationState: GenerationSt
val frame = frames[i] ?: continue
val insn = insnList[i]
if ((insn.opcode == Opcodes.ASTORE || insn.opcode == Opcodes.ALOAD) &&
(insn as VarInsnNode).`var` == localVariableNode.index) {
(insn as VarInsnNode).`var` == localVariableNode.index
) {
if (insn.getOpcode() == Opcodes.ASTORE) {
values.add(frame.top()!!)
} else {

View File

@@ -14057,6 +14057,70 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/directInvokeOptimization")
@TestDataPath("$PROJECT_ROOT")
public class DirectInvokeOptimization {
@Test
public void testAllFilesPresentInDirectInvokeOptimization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/directInvokeOptimization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("boundInnerContructorRef.kt")
public void testBoundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundInnerContructorRef.kt");
}
@Test
@TestMetadata("boundMemberRef.kt")
public void testBoundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundMemberRef.kt");
}
@Test
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/capturingLambda.kt");
}
@Test
@TestMetadata("contructorRef.kt")
public void testContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/contructorRef.kt");
}
@Test
@TestMetadata("simpleAnonymousFun.kt")
public void testSimpleAnonymousFun() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleAnonymousFun.kt");
}
@Test
@TestMetadata("simpleFunRef.kt")
public void testSimpleFunRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleFunRef.kt");
}
@Test
@TestMetadata("simpleLambda.kt")
public void testSimpleLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleLambda.kt");
}
@Test
@TestMetadata("unboundInnerContructorRef.kt")
public void testUnboundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundInnerContructorRef.kt");
}
@Test
@TestMetadata("unboundMemberRef.kt")
public void testUnboundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundMemberRef.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/elvis")
@TestDataPath("$PROJECT_ROOT")

View File

@@ -85,7 +85,7 @@ class Equals(val operator: IElementType) : IntrinsicMethod() {
// what comparison means. The optimization does not apply to `object == primitive` as equals
// could be overridden for the object.
if ((opToken == IrStatementOrigin.EQEQ || opToken == IrStatementOrigin.EXCLEQ) &&
((AsmUtil.isIntOrLongPrimitive(leftType) && !AsmUtil.isPrimitive(rightType)) ||
((AsmUtil.isIntOrLongPrimitive(leftType) && !isPrimitive(rightType)) ||
(AsmUtil.isIntOrLongPrimitive(rightType) && AsmUtil.isBoxedPrimitiveType(leftType)))
) {
val aValue = a.accept(codegen, data).materializedAt(leftType, a.type)

View File

@@ -27,31 +27,38 @@ import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
// TODO Implement hashCode on primitive types as a lowering.
object HashCode : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo) = with(codegen) {
val receiver = expression.dispatchReceiver ?: error("No receiver for hashCode: ${expression.render()}")
val result = receiver.accept(this, data).materialized()
val receiverIrType = receiver.type
val receiverJvmType = typeMapper.mapType(receiverIrType)
val receiverValue = receiver.accept(this, data).materialized()
val receiverType = receiverValue.type
val target = context.state.target
when {
irFunction.origin == JvmLoweredDeclarationOrigin.INLINE_CLASS_GENERATED_IMPL_METHOD ||
irFunction.origin == IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER ->
DescriptorAsmUtil.genHashCode(mv, mv, result.type, target)
target == JvmTarget.JVM_1_6 || !AsmUtil.isPrimitive(result.type) -> {
result.materializeAtBoxed(receiver.type)
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
irFunction.origin == IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER -> {
// TODO generate or lower IR for data class / inline class 'hashCode'?
DescriptorAsmUtil.genHashCode(mv, mv, receiverType, target)
}
else -> {
val boxedType = AsmUtil.boxType(result.type)
target >= JvmTarget.JVM_1_8 && AsmUtil.isPrimitive(receiverJvmType) -> {
val boxedType = AsmUtil.boxPrimitiveType(receiverJvmType)
?: throw AssertionError("Primitive type expected: $receiverJvmType")
receiverValue.materializeAt(receiverJvmType, receiverIrType)
mv.visitMethodInsn(
Opcodes.INVOKESTATIC,
boxedType.internalName,
"hashCode",
Type.getMethodDescriptor(Type.INT_TYPE, result.type),
Type.getMethodDescriptor(Type.INT_TYPE, receiverJvmType),
false
)
}
else -> {
receiverValue.materializeAtBoxed(receiverIrType)
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
}
}
MaterialValue(codegen, Type.INT_TYPE, codegen.context.irBuiltIns.intType)
}
}

View File

@@ -13,18 +13,6 @@ import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type
private fun ExpressionCodegen.checkTopValueForNull() {
mv.dup()
if (state.unifiedNullChecks) {
mv.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "checkNotNull", "(Ljava/lang/Object;)V", false)
} else {
val ifNonNullLabel = Label()
mv.ifnonnull(ifNonNullLabel)
mv.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "throwNpe", "()V", false)
mv.mark(ifNonNullLabel)
}
}
object IrCheckNotNull : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? {
val arg0 = expression.getValueArgument(0)!!.accept(codegen, data)
@@ -37,4 +25,16 @@ object IrCheckNotNull : IntrinsicMethod() {
arg0.materialized().also { codegen.checkTopValueForNull() }.discard()
}
}
private fun ExpressionCodegen.checkTopValueForNull() {
mv.dup()
if (state.unifiedNullChecks) {
mv.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "checkNotNull", "(Ljava/lang/Object;)V", false)
} else {
val ifNonNullLabel = Label()
mv.ifnonnull(ifNonNullLabel)
mv.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "throwNpe", "()V", false)
mv.mark(ifNonNullLabel)
}
}
}

View File

@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.backend.common.lower.SamEqualsHashCodeMethodsGenerator
import org.jetbrains.kotlin.backend.common.lower.parents
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
@@ -27,10 +28,7 @@ import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
@@ -113,6 +111,104 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
return FunctionReferenceBuilder(reference).build()
}
override fun visitCall(expression: IrCall): IrExpression {
if (expression.symbol.owner.isInvokeOperator()) {
when (val receiver = expression.dispatchReceiver) {
is IrFunctionReference -> {
rewriteDirectInvokeToFunctionReference(expression, receiver)?.let {
it.transformChildrenVoid()
return it
}
}
is IrBlock -> {
val last = receiver.statements.last()
if (last is IrFunctionReference) {
rewriteDirectInvokeToLambda(expression, receiver, last)?.let {
it.transformChildrenVoid()
return it
}
}
}
}
}
expression.transformChildrenVoid(this)
return expression
}
private fun IrFunction.isInvokeOperator(): Boolean {
// TODO
return name.asString() == "invoke"
}
private fun rewriteDirectInvokeToLambda(irInvokeCall: IrCall, irBlock: IrBlock, lastFunRef: IrFunctionReference): IrExpression? {
val callee = lastFunRef.symbol.owner
if (callee.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA && !callee.isAnonymousFunction)
return null
if (callee.parents.any { it is IrSimpleFunction && it.isInline }) {
// TODO investigate why inliner gets confused when we pass it a function with some optimized direct invoke.
return null
}
val irDirectCall = rewriteDirectInvokeToFunctionReference(irInvokeCall, lastFunRef)
?: return null
val newBlock = IrBlockImpl(irBlock.startOffset, irBlock.endOffset, irDirectCall.type)
for (i in 0 until irBlock.statements.lastIndex) {
newBlock.statements.add(irBlock.statements[i])
}
newBlock.statements.add(irDirectCall)
return newBlock
}
private fun rewriteDirectInvokeToFunctionReference(irInvokeCall: IrCall, irFunRef: IrFunctionReference): IrExpression? {
// TODO deal with type parameters somehow?
// It seems we can't encounter them in the code written by user,
// but this might be important later if we actually perform inlining and optimizations on IR.
return when (val irFun = irFunRef.symbol.owner) {
is IrSimpleFunction -> {
if (irFun.typeParameters.isNotEmpty()) return null
IrCallImpl(
irInvokeCall.startOffset, irInvokeCall.endOffset, irInvokeCall.type,
irFun.symbol,
typeArgumentsCount = irFun.typeParameters.size, valueArgumentsCount = irFun.valueParameters.size
).apply {
copyReceiverAndValueArgumentsForDirectInvoke(irFunRef, irInvokeCall)
}
}
is IrConstructor ->
IrConstructorCallImpl(
irInvokeCall.startOffset, irInvokeCall.endOffset, irInvokeCall.type,
irFun.symbol,
typeArgumentsCount = irFun.typeParameters.size,
constructorTypeArgumentsCount = 0,
valueArgumentsCount = irFun.valueParameters.size
).apply {
copyReceiverAndValueArgumentsForDirectInvoke(irFunRef, irInvokeCall)
}
else ->
throw AssertionError("Simple function or constructor expected: ${irFun.render()}")
}
}
private fun IrFunctionAccessExpression.copyReceiverAndValueArgumentsForDirectInvoke(
irFunRef: IrFunctionReference,
irInvokeCall: IrFunctionAccessExpression
) {
val irFun = irFunRef.symbol.owner
var invokeArgIndex = 0
if (irFun.dispatchReceiverParameter != null) {
dispatchReceiver = irFunRef.dispatchReceiver ?: irInvokeCall.getValueArgument(invokeArgIndex++)
}
if (irFun.extensionReceiverParameter != null) {
extensionReceiver = irFunRef.extensionReceiver ?: irInvokeCall.getValueArgument(invokeArgIndex++)
}
if (invokeArgIndex + valueArgumentsCount != irInvokeCall.valueArgumentsCount) {
throw AssertionError("Mismatching value arguments: $invokeArgIndex arguments used for receivers\n${irInvokeCall.dump()}")
}
for (i in 0 until valueArgumentsCount) {
putValueArgument(i, irInvokeCall.getValueArgument(invokeArgIndex++))
}
}
private fun wrapLambdaReferenceWithIndySamConversion(
expression: IrBlock,
reference: IrFunctionReference,

View File

@@ -10,16 +10,17 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlock
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.codegen.intrinsics.Not
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.irGetField
import org.jetbrains.kotlin.ir.builders.irSetField
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
@@ -64,6 +65,41 @@ class JvmOptimizationLowering(val context: JvmBackendContext) : FileLoweringPass
else -> null
}
private class SafeCallInfo(
val scopeSymbol: IrSymbol,
val tmpVal: IrVariable,
val ifNullBranch: IrBranch,
val ifNotNullBranch: IrBranch
)
private fun parseSafeCall(expression: IrExpression): SafeCallInfo? {
val block = expression as? IrBlock ?: return null
if (block.origin != IrStatementOrigin.SAFE_CALL) return null
if (block.statements.size != 2) return null
val tmpVal = block.statements[0] as? IrVariable ?: return null
val scopeOwner = tmpVal.parent as? IrDeclaration ?: return null
val scopeSymbol = scopeOwner.symbol
val whenExpr = block.statements[1] as? IrWhen ?: return null
if (whenExpr.branches.size != 2) return null
val ifNullBranch = whenExpr.branches[0]
val ifNullBranchCondition = ifNullBranch.condition
if (ifNullBranchCondition !is IrCall) return null
if (ifNullBranchCondition.symbol != context.irBuiltIns.eqeqSymbol) return null
val arg0 = ifNullBranchCondition.getValueArgument(0)
if (arg0 !is IrGetValue || arg0.symbol != tmpVal.symbol) return null
val arg1 = ifNullBranchCondition.getValueArgument(1)
if (arg1 !is IrConst<*> || arg1.value != null) return null
val ifNullBranchResult = ifNullBranch.result
if (ifNullBranchResult !is IrConst<*> || ifNullBranchResult.value != null) return null
val ifNotNullBranch = whenExpr.branches[1]
return SafeCallInfo(scopeSymbol, tmpVal, ifNullBranch, ifNotNullBranch)
}
private fun IrType.isJvmPrimitive(): Boolean =
AsmUtil.isPrimitive(context.typeMapper.mapType(this))
override fun lower(irFile: IrFile) {
val transformer = object : IrElementTransformer<IrClass?> {
@@ -105,20 +141,95 @@ class JvmOptimizationLowering(val context: JvmBackendContext) : FileLoweringPass
}
getOperandsIfCallToEQEQOrEquals(expression)?.let { (left, right) ->
return when {
left.isNullConst() && right.isNullConst() ->
IrConstImpl.constTrue(expression.startOffset, expression.endOffset, context.irBuiltIns.booleanType)
if (left.isNullConst() && right.isNullConst())
return IrConstImpl.constTrue(expression.startOffset, expression.endOffset, context.irBuiltIns.booleanType)
left.isNullConst() && right is IrConst<*> || right.isNullConst() && left is IrConst<*> ->
IrConstImpl.constFalse(expression.startOffset, expression.endOffset, context.irBuiltIns.booleanType)
if (left.isNullConst() && right is IrConst<*> || right.isNullConst() && left is IrConst<*>)
return IrConstImpl.constFalse(expression.startOffset, expression.endOffset, context.irBuiltIns.booleanType)
else -> expression
val safeCallLeft = parseSafeCall(left)
if (safeCallLeft != null && right.type.isJvmPrimitive()) {
return rewriteSafeCallEqeqPrimitive(safeCallLeft, right, expression)
}
val safeCallRight = parseSafeCall(right)
if (safeCallRight != null && left.type.isJvmPrimitive()) {
return rewritePrimitiveEqeqSafeCall(left, safeCallRight, expression)
}
return expression
}
return expression
}
private fun rewriteSafeCallEqeqPrimitive(safeCall: SafeCallInfo, primitive: IrExpression, eqeqCall: IrCall): IrExpression =
context.createJvmIrBuilder(safeCall.scopeSymbol).run {
// Fuze safe call with primitive equality to avoid boxing the primitive.
// 'a?.<...> == p' becomes:
// {
// val tmp = a
// when {
// tmp == null -> false
// else -> tmp == p
// }
// }
irBlock {
+safeCall.tmpVal
+irWhen(
eqeqCall.type,
listOf(
irBranch(safeCall.ifNullBranch.condition, irFalse()),
irElseBranch(
irCall(eqeqCall.symbol).apply {
putValueArgument(0, safeCall.ifNotNullBranch.result)
putValueArgument(1, primitive)
}
)
)
)
}
}
private fun rewritePrimitiveEqeqSafeCall(primitive: IrExpression, safeCall: SafeCallInfo, eqeqCall: IrCall): IrExpression =
context.createJvmIrBuilder(safeCall.scopeSymbol).run {
// Fuze safe call with primitive equality to avoid boxing the primitive.
// 'p == a?.<...>' becomes:
// {
// val tmp_p = p // should evaluate 'p' before 'a'
// val tmp = a
// when {
// tmp == null -> false
// else -> tmp_p == tmp
// }
// }
// 'tmp_p' above could be elided if 'p' is a variable or a constant.
irBlock {
val lhs = when (primitive) {
is IrGetValue,
is IrConst<*> ->
primitive
else -> {
val tmp = irTemporary(primitive)
irGet(tmp)
}
}
+safeCall.tmpVal
+irWhen(
eqeqCall.type,
listOf(
irBranch(safeCall.ifNullBranch.condition, irFalse()),
irElseBranch(
irCall(eqeqCall.symbol).apply {
putValueArgument(0, lhs)
putValueArgument(1, safeCall.ifNotNullBranch.result)
}
)
)
)
}
}
private fun IrType.isByteOrShort() = isByte() || isShort()
// For `==` and `!=`, get rid of safe calls to convert `Byte?` or `Short?` to `Int?`.

View File

@@ -131,6 +131,8 @@ val IrDeclaration.isTopLevelDeclaration get() =
val IrDeclaration.isAnonymousObject get() = this is IrClass && name == SpecialNames.NO_NAME_PROVIDED
val IrDeclaration.isAnonymousFunction get() = this is IrSimpleFunction && name == SpecialNames.NO_NAME_PROVIDED
val IrDeclaration.isLocal: Boolean
get() {
var current: IrElement = this

View File

@@ -0,0 +1,12 @@
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 0 invoke
class Outer (val x: String) {
inner class Inner(val y: String) {
val yx = y + x
}
}
fun box() =
Outer("K")::Inner.invoke("O").yx

View File

@@ -0,0 +1,10 @@
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 0 invoke
class C(val x: String) {
fun foo(s: String) = x + s
}
fun box() =
C("O")::foo.invoke("K")

View File

@@ -0,0 +1,11 @@
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 0 invoke
fun box(): String {
var ok = "FAILED"
{ s: String ->
ok = s
}("OK")
return ok
}

View File

@@ -0,0 +1,10 @@
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 0 invoke
class C(x: String, y: String) {
val yx = y + x
}
fun box() =
::C.invoke("K", "O").yx

View File

@@ -0,0 +1,10 @@
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 0 invoke
fun box() =
(fun (s: String): String {
var ok = "O"
ok += s
return ok
}).invoke("K")

View File

@@ -0,0 +1,8 @@
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 0 invoke
fun ok(s: String) = "O" + s
fun box() =
::ok.invoke("K")

View File

@@ -0,0 +1,10 @@
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 0 invoke
fun box() =
{ s: String ->
var ok = "O"
ok += s
ok
}.invoke("K")

View File

@@ -0,0 +1,12 @@
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 0 invoke
class Outer (val x: String) {
inner class Inner(val y: String) {
val yx = y + x
}
}
fun box() =
(Outer::Inner).invoke(Outer("K"), "O").yx

View File

@@ -0,0 +1,2 @@
fun box(): String =
(String::plus)("O", "K")

View File

@@ -5,13 +5,13 @@
// CHECK_BYTECODE_TEXT
// JVM_IR_TEMPLATES
// 0 java/lang/invoke/LambdaMetafactory\.metafactory
// 1 final class BigArityLambdaKt\$box\$1
// 1 final class BigArityLambdaKt\$box\$lam\$1
fun box() =
{ p0: String, p1: String, p2: Int, p3: Int, p4: Int, p5: Int, p6: Int, p7: Int, p8: Int, p9: Int,
p10: Int, p11: Int, p12: Int, p13: Int, p14: Int, p15: Int, p16: Int, p17: Int, p18: Int, p19: Int,
p20: Int, p21: Int, p22: Int, p23: Int, p24: Int, p25: Int, p26: Int, p27: Int, p28: Int, p29: Int
fun box(): String {
val lam = { p0: String, p1: String, p2: Int, p3: Int, p4: Int, p5: Int, p6: Int, p7: Int, p8: Int, p9: Int,
p10: Int, p11: Int, p12: Int, p13: Int, p14: Int, p15: Int, p16: Int, p17: Int, p18: Int, p19: Int,
p20: Int, p21: Int, p22: Int, p23: Int, p24: Int, p25: Int, p26: Int, p27: Int, p28: Int, p29: Int
-> p0 + p1
}(
"O", "K", 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
)
}
return lam("O", "K", 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29)
}

View File

@@ -8,5 +8,6 @@
fun box(): String {
val ok = "OK"
return { ok }()
val lam = { ok }
return lam()
}

View File

@@ -8,6 +8,7 @@
fun box(): String {
var ok = "Failed"
{ ok = "OK" }()
val lam = { ok = "OK" }
lam()
return ok
}

View File

@@ -6,4 +6,11 @@
// JVM_IR_TEMPLATES
// 3 java/lang/invoke/LambdaMetafactory
fun box() = { { "O" }() + { "K" }() }()
fun box(): String {
val lam1 = {
val lamO = { "O" }
val lamK = { "K" }
lamO() + lamK()
}
return lam1()
}

View File

@@ -7,7 +7,8 @@
// 1 java/lang/invoke/LambdaMetafactory
fun box(): String {
val test = { i: Int -> i + 40 }(2)
val lam = { i: Int -> i + 40 }
val test = lam(2)
if (test != 42) return "Failed: test=$test"
return "OK"

View File

@@ -6,4 +6,7 @@
// JVM_IR_TEMPLATES
// 1 java/lang/invoke/LambdaMetafactory
fun box() = { "OK" }()
fun box(): String {
val lam = { "OK" }
return lam()
}

View File

@@ -9,6 +9,7 @@
var ok = "Failed"
fun box(): String {
{ ok = "OK" }()
val lam = { ok = "OK" }
lam()
return ok
}

View File

@@ -4,16 +4,18 @@
fun box(): String {
val classInLambda = {
val lambda = {
class Z {}
Z()
}()
}
val classInLambda = lambda()
val enclosingMethod = classInLambda.javaClass.getEnclosingMethod()
if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod"
val enclosingClass = classInLambda.javaClass.getEnclosingClass()!!.getName()
if (enclosingClass != "ClassInLambdaKt\$box\$classInLambda\$1") return "enclosing class: $enclosingClass"
if (enclosingClass != "ClassInLambdaKt\$box\$lambda\$1") return "enclosing class: $enclosingClass"
val declaringClass = classInLambda.javaClass.getDeclaringClass()
if (declaringClass != null) return "class has a declaring class"

View File

@@ -3,16 +3,17 @@
// WITH_REFLECT
fun box(): String {
val objectInLambda = {
val lambda = {
object : Any () {}
}()
}
val objectInLambda = lambda()
val enclosingMethod = objectInLambda.javaClass.getEnclosingMethod()
if (enclosingMethod?.getName() != "invoke") return "method: $enclosingMethod"
val enclosingClass = objectInLambda.javaClass.getEnclosingClass()!!.getName()
if (enclosingClass != "ObjectInLambdaKt\$box\$objectInLambda\$1") return "enclosing class: $enclosingClass"
if (enclosingClass != "ObjectInLambdaKt\$box\$lambda\$1") return "enclosing class: $enclosingClass"
val declaringClass = objectInLambda.javaClass.getDeclaringClass()
if (declaringClass != null) return "anonymous object has a declaring class"

View File

@@ -1,11 +1,58 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND_FIR: JVM_IR
fun foo() {
val x: Int? = 6
val hc = x!!.hashCode()
fun testBoolean(): Int {
val b: Boolean? = true
return b!!.hashCode()
}
fun testByte(): Int {
val b: Byte? = 1.toByte()
return b!!.hashCode()
}
fun testChar(): Int {
val c: Char? = 'x'
return c!!.hashCode()
}
fun testShort(): Int {
val s: Short? = 1.toShort()
return s!!.hashCode()
}
fun testInt(): Int {
val i: Int? = 42
return i!!.hashCode()
}
fun testLong(): Int {
val l: Long? = 42L
return l!!.hashCode()
}
fun testFloat(): Int {
val f: Float? = 0.0f
return f!!.hashCode()
}
fun testDouble(): Int {
val d: Double? = 0.0
return d!!.hashCode()
}
// 1 java/lang/Boolean.hashCode \(Z\)I
// 1 java/lang/Character.hashCode \(C\)I
// 1 java/lang/Byte.hashCode \(B\)I
// 1 java/lang/Short.hashCode \(S\)I
// 1 java/lang/Integer.hashCode \(I\)I
// 0 java/lang/Integer.valueOf
// 1 java/lang/Long.hashCode \(J\)I
// 1 java/lang/Float.hashCode \(F\)I
// 1 java/lang/Double.hashCode \(D\)I
// 0 valueOf
// 0 byteValue
// 0 shortValue
// 0 intValue
// 0 longValue
// 0 floatValue
// 0 doubleValue
// 0 charValue

View File

@@ -1,7 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
// TODO KT-36646 Don't box primitive values in equality comparison with nullable primitive values in JVM_IR
fun Long.id() = this
fun String.drop2() = if (length >= 2) subSequence(2, length) else null

View File

@@ -1,26 +1,31 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
// TODO KT-36637 Trivial closure optimizatin in JVM_IR
fun test() {
fun local(){
{
val lam = {
//static instance access
local()
}()
}
lam()
}
//static instance access
{
val lam = {
//static instance access
local()
}()
}
lam()
//static instance access
(::local)()
val cr = ::local
cr()
}
// JVM_TEMPLATES
// 3 GETSTATIC ConstClosureOptimizationKt\$test\$1\.INSTANCE
// 1 GETSTATIC ConstClosureOptimizationKt\$test\$2\.INSTANCE
// 1 GETSTATIC ConstClosureOptimizationKt\$test\$3\.INSTANCE
// JVM_IR_TEMPLATES
// 1 GETSTATIC ConstClosureOptimizationKt\$test\$cr\$1.INSTANCE
// 1 GETSTATIC ConstClosureOptimizationKt\$test\$lam\$1.INSTANCE
// 1 GETSTATIC ConstClosureOptimizationKt\$test\$local\$lam\$1.INSTANCE

View File

@@ -3,7 +3,8 @@ class Z{
fun a(s: Int) {}
fun b() {
(Z::a)(Z(), 1)
val cr = (Z::a)
cr(Z(), 1)
}
}

View File

@@ -1,6 +1,7 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun test() {
1.(fun Int.() = 2)()
val fn = fun Int.() = 2
1.fn()
}
// 1 invoke \(I\)I

View File

@@ -1,6 +1,7 @@
fun test() {
{
{}()
val lam = {}
lam()
}()
}
@@ -11,16 +12,18 @@ inline fun ifun(s: () -> Unit) {
fun test2() {
var z = 1;
ifun {
{ z = 2 }()
val lam = { z = 2 }
lam()
}
}
// 1 class DeleteClassOnTransformationKt\$test\$1\$1
// JVM_TEMPLATES:
// 1 class DeleteClassOnTransformationKt\$test\$1\$1
// 0 class DeleteClassOnTransformationKt\$test2\$1\$1
// 1 class DeleteClassOnTransformationKt\$test2\$\$inlined\$ifun\$lambda\$1
// JVM_IR_TEMPLATES:
// 1 class DeleteClassOnTransformationKt\$test2\$1\$1
// 0 class DeleteClassOnTransformationKt\$test2\$\$inlined
// 3 final class
// 1 class DeleteClassOnTransformationKt\$test\$1\$lam\$1
// 1 class DeleteClassOnTransformationKt\$test2\$1\$lam\$1

View File

@@ -3,7 +3,14 @@
// JVM_TARGET: 1.8
// LAMBDAS: INDY
fun test() = { { "O" }() + { "K" }() }()
fun test(): String {
val lam = {
val lamO = { "O" }
val lamK = { "K" }
lamO() + lamK()
}
return lam()
}
// JVM_IR_TEMPLATES
// 3 INVOKEDYNAMIC

View File

@@ -2,12 +2,12 @@ fun box(): String {
var encl1 = "fail"
var encl2 = "fail"
test {
{
val lam1 = {
encl1 = "OK"
{
encl2 = "OK"
}()
}()
val lam2 = { encl2 = "OK" }
lam2()
}
lam1()
}
return "OK"
@@ -28,7 +28,5 @@ inline fun test(s: () -> Unit) {
// JVM_IR_TEMPLATES
// 5 INNERCLASS
// 3 INNERCLASS Kt10259Kt\$box\$1\$1\s
// 2 INNERCLASS Kt10259Kt\$box\$1\$1\$1
// 1 class Kt10259Kt\$box\$1\$1\ extends
// 1 class Kt10259Kt\$box\$1\$1\$1 extends
// 3 INNERCLASS Kt10259Kt\$box\$1\$lam1\$1 null null
// 2 INNERCLASS Kt10259Kt\$box\$1\$lam1\$1\$lam2\$1

View File

@@ -1,11 +1,11 @@
fun box(): String {
var encl1 = "fail";
test {
{
{
encl1 = "OK"
}()
}()
val lam1 = {
val lam2 = { encl1 = "OK" }
lam2()
}
lam1()
}
return encl1
@@ -31,7 +31,7 @@ inline fun test(crossinline s: () -> Unit) {
// 2 INNERCLASS Kt10259_3Kt\$box\$\$inlined\$test\$1\$1\$lambda\$1\$1\s
// NB JVM_IR generates
// final static INNERCLASS Kt10259_3Kt$box$1$1 null null
// final static INNERCLASS Kt10259_3Kt$box$1$lam1$1 null null
// public final static INNERCLASS Kt10259_3Kt$test$1 null null
// in Kt10259_3Kt.
// Although Oracle JVM doesn't check for consistency of InnerClasses attributes,
@@ -39,7 +39,10 @@ inline fun test(crossinline s: () -> Unit) {
// JVM_IR_TEMPLATES
// 14 INNERCLASS
// 3 INNERCLASS Kt10259_3Kt\$box\$1\$1\s
// 2 INNERCLASS Kt10259_3Kt\$box\$1\$1\$1\s
// 3 INNERCLASS Kt10259_3Kt\$test\$1\s
// 2 INNERCLASS Kt10259_3Kt\$test\$1\$1\s
// 3 INNERCLASS Kt10259_3Kt\$box\$1\$lam1\$1 null null
// 2 INNERCLASS Kt10259_3Kt\$box\$1\$lam1\$1\$lam2\$1 null null
// 2 INNERCLASS Kt10259_3Kt\$box\$\$inlined\$test\$1 null null
// 2 INNERCLASS Kt10259_3Kt\$box\$\$inlined\$test\$1\$1 null null
// 3 INNERCLASS Kt10259_3Kt\$test\$1 null null
// 2 INNERCLASS Kt10259_3Kt\$test\$1\$1 null null

View File

@@ -14057,6 +14057,70 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/directInvokeOptimization")
@TestDataPath("$PROJECT_ROOT")
public class DirectInvokeOptimization {
@Test
public void testAllFilesPresentInDirectInvokeOptimization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/directInvokeOptimization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@Test
@TestMetadata("boundInnerContructorRef.kt")
public void testBoundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundInnerContructorRef.kt");
}
@Test
@TestMetadata("boundMemberRef.kt")
public void testBoundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundMemberRef.kt");
}
@Test
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/capturingLambda.kt");
}
@Test
@TestMetadata("contructorRef.kt")
public void testContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/contructorRef.kt");
}
@Test
@TestMetadata("simpleAnonymousFun.kt")
public void testSimpleAnonymousFun() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleAnonymousFun.kt");
}
@Test
@TestMetadata("simpleFunRef.kt")
public void testSimpleFunRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleFunRef.kt");
}
@Test
@TestMetadata("simpleLambda.kt")
public void testSimpleLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleLambda.kt");
}
@Test
@TestMetadata("unboundInnerContructorRef.kt")
public void testUnboundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundInnerContructorRef.kt");
}
@Test
@TestMetadata("unboundMemberRef.kt")
public void testUnboundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundMemberRef.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/elvis")
@TestDataPath("$PROJECT_ROOT")

View File

@@ -14057,6 +14057,70 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/directInvokeOptimization")
@TestDataPath("$PROJECT_ROOT")
public class DirectInvokeOptimization {
@Test
public void testAllFilesPresentInDirectInvokeOptimization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/directInvokeOptimization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("boundInnerContructorRef.kt")
public void testBoundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundInnerContructorRef.kt");
}
@Test
@TestMetadata("boundMemberRef.kt")
public void testBoundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundMemberRef.kt");
}
@Test
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/capturingLambda.kt");
}
@Test
@TestMetadata("contructorRef.kt")
public void testContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/contructorRef.kt");
}
@Test
@TestMetadata("simpleAnonymousFun.kt")
public void testSimpleAnonymousFun() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleAnonymousFun.kt");
}
@Test
@TestMetadata("simpleFunRef.kt")
public void testSimpleFunRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleFunRef.kt");
}
@Test
@TestMetadata("simpleLambda.kt")
public void testSimpleLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleLambda.kt");
}
@Test
@TestMetadata("unboundInnerContructorRef.kt")
public void testUnboundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundInnerContructorRef.kt");
}
@Test
@TestMetadata("unboundMemberRef.kt")
public void testUnboundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundMemberRef.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/elvis")
@TestDataPath("$PROJECT_ROOT")

View File

@@ -11499,6 +11499,64 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
}
}
@TestMetadata("compiler/testData/codegen/box/directInvokeOptimization")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class DirectInvokeOptimization extends AbstractLightAnalysisModeTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInDirectInvokeOptimization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/directInvokeOptimization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@TestMetadata("boundInnerContructorRef.kt")
public void testBoundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundInnerContructorRef.kt");
}
@TestMetadata("boundMemberRef.kt")
public void testBoundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundMemberRef.kt");
}
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/capturingLambda.kt");
}
@TestMetadata("contructorRef.kt")
public void testContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/contructorRef.kt");
}
@TestMetadata("simpleAnonymousFun.kt")
public void testSimpleAnonymousFun() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleAnonymousFun.kt");
}
@TestMetadata("simpleFunRef.kt")
public void testSimpleFunRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleFunRef.kt");
}
@TestMetadata("simpleLambda.kt")
public void testSimpleLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleLambda.kt");
}
@TestMetadata("unboundInnerContructorRef.kt")
public void testUnboundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundInnerContructorRef.kt");
}
@TestMetadata("unboundMemberRef.kt")
public void testUnboundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundMemberRef.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/elvis")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)

View File

@@ -10298,6 +10298,64 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
}
}
@TestMetadata("compiler/testData/codegen/box/directInvokeOptimization")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class DirectInvokeOptimization extends AbstractIrJsCodegenBoxES6Test {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
}
public void testAllFilesPresentInDirectInvokeOptimization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/directInvokeOptimization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
@TestMetadata("boundInnerContructorRef.kt")
public void testBoundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundInnerContructorRef.kt");
}
@TestMetadata("boundMemberRef.kt")
public void testBoundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundMemberRef.kt");
}
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/capturingLambda.kt");
}
@TestMetadata("contructorRef.kt")
public void testContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/contructorRef.kt");
}
@TestMetadata("simpleAnonymousFun.kt")
public void testSimpleAnonymousFun() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleAnonymousFun.kt");
}
@TestMetadata("simpleFunRef.kt")
public void testSimpleFunRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleFunRef.kt");
}
@TestMetadata("simpleLambda.kt")
public void testSimpleLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleLambda.kt");
}
@TestMetadata("unboundInnerContructorRef.kt")
public void testUnboundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundInnerContructorRef.kt");
}
@TestMetadata("unboundMemberRef.kt")
public void testUnboundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundMemberRef.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/elvis")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)

View File

@@ -9709,6 +9709,64 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
}
}
@TestMetadata("compiler/testData/codegen/box/directInvokeOptimization")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class DirectInvokeOptimization extends AbstractIrJsCodegenBoxTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
}
public void testAllFilesPresentInDirectInvokeOptimization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/directInvokeOptimization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@TestMetadata("boundInnerContructorRef.kt")
public void testBoundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundInnerContructorRef.kt");
}
@TestMetadata("boundMemberRef.kt")
public void testBoundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundMemberRef.kt");
}
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/capturingLambda.kt");
}
@TestMetadata("contructorRef.kt")
public void testContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/contructorRef.kt");
}
@TestMetadata("simpleAnonymousFun.kt")
public void testSimpleAnonymousFun() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleAnonymousFun.kt");
}
@TestMetadata("simpleFunRef.kt")
public void testSimpleFunRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleFunRef.kt");
}
@TestMetadata("simpleLambda.kt")
public void testSimpleLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleLambda.kt");
}
@TestMetadata("unboundInnerContructorRef.kt")
public void testUnboundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundInnerContructorRef.kt");
}
@TestMetadata("unboundMemberRef.kt")
public void testUnboundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundMemberRef.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/elvis")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)

View File

@@ -9709,6 +9709,64 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
}
}
@TestMetadata("compiler/testData/codegen/box/directInvokeOptimization")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class DirectInvokeOptimization extends AbstractJsCodegenBoxTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
}
public void testAllFilesPresentInDirectInvokeOptimization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/directInvokeOptimization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
@TestMetadata("boundInnerContructorRef.kt")
public void testBoundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundInnerContructorRef.kt");
}
@TestMetadata("boundMemberRef.kt")
public void testBoundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundMemberRef.kt");
}
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/capturingLambda.kt");
}
@TestMetadata("contructorRef.kt")
public void testContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/contructorRef.kt");
}
@TestMetadata("simpleAnonymousFun.kt")
public void testSimpleAnonymousFun() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleAnonymousFun.kt");
}
@TestMetadata("simpleFunRef.kt")
public void testSimpleFunRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleFunRef.kt");
}
@TestMetadata("simpleLambda.kt")
public void testSimpleLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleLambda.kt");
}
@TestMetadata("unboundInnerContructorRef.kt")
public void testUnboundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundInnerContructorRef.kt");
}
@TestMetadata("unboundMemberRef.kt")
public void testUnboundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundMemberRef.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/elvis")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)

View File

@@ -4627,6 +4627,64 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
}
}
@TestMetadata("compiler/testData/codegen/box/directInvokeOptimization")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class DirectInvokeOptimization extends AbstractIrCodegenBoxWasmTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
}
public void testAllFilesPresentInDirectInvokeOptimization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/directInvokeOptimization"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
@TestMetadata("boundInnerContructorRef.kt")
public void testBoundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundInnerContructorRef.kt");
}
@TestMetadata("boundMemberRef.kt")
public void testBoundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/boundMemberRef.kt");
}
@TestMetadata("capturingLambda.kt")
public void testCapturingLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/capturingLambda.kt");
}
@TestMetadata("contructorRef.kt")
public void testContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/contructorRef.kt");
}
@TestMetadata("simpleAnonymousFun.kt")
public void testSimpleAnonymousFun() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleAnonymousFun.kt");
}
@TestMetadata("simpleFunRef.kt")
public void testSimpleFunRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleFunRef.kt");
}
@TestMetadata("simpleLambda.kt")
public void testSimpleLambda() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/simpleLambda.kt");
}
@TestMetadata("unboundInnerContructorRef.kt")
public void testUnboundInnerContructorRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundInnerContructorRef.kt");
}
@TestMetadata("unboundMemberRef.kt")
public void testUnboundMemberRef() throws Exception {
runTest("compiler/testData/codegen/box/directInvokeOptimization/unboundMemberRef.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/elvis")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)