diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 2b37f240ba0..ce0d8442c28 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -620,6 +620,7 @@ public class FunctionCodegen { isReleaseCoroutines); } + Label methodEntry = null; Label methodEnd; int functionFakeIndex = -1; @@ -649,14 +650,14 @@ public class FunctionCodegen { functionDescriptor.getValueParameters(), isStaticMethod(context.getContextKind(), functionDescriptor) ); if (context.isInlineMethodContext()) { - functionFakeIndex = frameMap.enterTemp(Type.INT_TYPE); + functionFakeIndex = newFakeTempIndex(mv, frameMap); } if (context instanceof InlineLambdaContext) { - lambdaFakeIndex = frameMap.enterTemp(Type.INT_TYPE); + lambdaFakeIndex = newFakeTempIndex(mv, frameMap); } - Label methodEntry = new Label(); + methodEntry = new Label(); mv.visitLabel(methodEntry); context.setMethodStartLabel(methodEntry); @@ -708,10 +709,11 @@ public class FunctionCodegen { //TODO: it's best to move all below logic to 'generateLocalVariableTable' method if (context.isInlineMethodContext() && functionFakeIndex != -1) { + assert methodEntry != null : "methodEntry is not initialized"; mv.visitLocalVariable( JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION + typeMapper.mapAsmMethod(functionDescriptor).getName(), Type.INT_TYPE.getDescriptor(), null, - methodBegin, methodEnd, + methodEntry, methodEnd, functionFakeIndex); } @@ -728,14 +730,22 @@ public class FunctionCodegen { functionName = inlineArgumentDescriptor.getContainingDeclaration().getName().asString(); } } + assert methodEntry != null : "methodEntry is not initialized"; mv.visitLocalVariable( JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT + "-" + functionName + "-" + lambdaLocalName, Type.INT_TYPE.getDescriptor(), null, - methodBegin, methodEnd, + methodEntry, methodEnd, lambdaFakeIndex); } } + private static int newFakeTempIndex(@NotNull MethodVisitor mv, FrameMap frameMap) { + int fakeIndex = frameMap.enterTemp(Type.INT_TYPE); + mv.visitLdcInsn(0); + mv.visitVarInsn(ISTORE, fakeIndex); + return fakeIndex; + } + private static boolean isCompatibilityStubInDefaultImpls( @NotNull FunctionDescriptor functionDescriptor, @NotNull MethodContext context, diff --git a/compiler/testData/codegen/bytecodeText/inline/inlineArgumentSlots.kt b/compiler/testData/codegen/bytecodeText/inline/inlineArgumentSlots.kt new file mode 100644 index 00000000000..7f6ae29d319 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inline/inlineArgumentSlots.kt @@ -0,0 +1,54 @@ +// WITH_RUNTIME + +class Range(val min: T, val max: T) + +class Sprite + +class A { + private fun calcSpriteSizeRange(layoutSize: Int, + sprites: Map, + minMargin: Int, + range: Range) + : Pair, Int> { + val count = sprites.count() + var spriteBounds = layoutSize / count.toFloat() + require(spriteBounds * count <= layoutSize) { + val result = spriteBounds * count <= layoutSize + "Algorithm incorrect: $spriteBounds * " + + "$count == $result <= $layoutSize" + } + val adjustedMargin = minMargin + (minMargin / count.toFloat()) + spriteBounds -= adjustedMargin + var size = spriteBounds + require((size * count) + minMargin * (count + 1) + <= layoutSize) { + val result = size * count + minMargin * (count + 1) + "Algorithm incorrect: $size * $count + " + + "$minMargin * ($count + 1) == $result <= $layoutSize" + } + size = kotlin.math.min(size, range.max.toFloat()) + require(size > 0) { + "Maximum palantir size ${size.toInt()} > 0." + } + val minSize = + if (range.min > size) { + size + } else { + range.min.toFloat() + } + val margin = (layoutSize - (size * count)) / (count + 1) + val adjustedRange = Range(minSize.toInt(), size.toInt()) + val requiredSize = + calcRequiredLayoutSize(count, adjustedRange.max, margin.toInt()) + require(requiredSize <= layoutSize) { + "requiredSize <= layoutSize -> " + + "$requiredSize <= $layoutSize" + } + + return Pair(adjustedRange, margin.toInt()) + } +} + +fun calcRequiredLayoutSize(count: Int, max: Int, toInt: Int) = 0 + +// 2 ISTORE 10 \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 0c92f434b1d..c98f225b2fe 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1948,6 +1948,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/inline/finallyMarkers.kt"); } + @TestMetadata("inlineArgumentSlots.kt") + public void testInlineArgumentSlots() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/inline/inlineArgumentSlots.kt"); + } + @TestMetadata("inlineReturnsNothing1.kt") public void testInlineReturnsNothing1() throws Exception { runTest("compiler/testData/codegen/bytecodeText/inline/inlineReturnsNothing1.kt");