From d985f56b8d348b4d6d27c68af84417da50989522 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Sat, 17 Oct 2015 15:58:46 +0300 Subject: [PATCH] Fix local variable shift for inline functions --- .../kotlin/codegen/inline/InlineCodegen.java | 7 ++++++- .../codegen/inline/InlineCodegenUtil.java | 19 +++++++++++++++++++ .../kotlin/codegen/inline/MethodInliner.java | 3 ++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java index d59917095bb..781e5befce6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java @@ -706,7 +706,12 @@ public class InlineCodegen extends CallGenerator { FrameMap frameMap = finallyCodegen.getFrameMap(); FrameMap.Mark mark = frameMap.mark(); - while (frameMap.getCurrentSize() < processor.getNextFreeLocalIndex()) { + int marker = -1; + Set intervals = processor.getLocalVarsMetaInfo().getCurrentIntervals(); + for (LocalVarNodeWrapper interval : intervals) { + marker = Math.max(interval.getNode().index + 1, marker); + } + while (frameMap.getCurrentSize() < Math.max(processor.getNextFreeLocalIndex(), offsetForFinallyLocalVar + marker)) { frameMap.enterTemp(Type.INT_TYPE); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java index 27f5e48a62e..5f17efb7e40 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegenUtil.java @@ -492,4 +492,23 @@ public class InlineCodegenUtil { public static boolean isStoreInstruction(int opcode) { return opcode >= Opcodes.ISTORE && opcode <= Opcodes.ASTORE; } + + public static int calcMarkerShift(Parameters parameters, MethodNode node) { + int markerShiftTemp = getIndexAfterLastMarker(node); + return markerShiftTemp - parameters.getRealArgsSizeOnStack() + parameters.getArgsSizeOnStack(); + } + + protected static int getIndexAfterLastMarker(MethodNode node) { + int markerShiftTemp = -1; + for (LocalVariableNode variable : node.localVariables) { + if (isFakeLocalVariableForInline(variable.name)) { + markerShiftTemp = Math.max(markerShiftTemp, variable.index + 1); + } + } + return markerShiftTemp; + } + + public static boolean isFakeLocalVariableForInline(@NotNull String name) { + return name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) || name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT); + } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java index e2a18e7e1df..9c3896115ee 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java @@ -155,6 +155,7 @@ public class MethodInliner { RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(resultNode.access, resultNode.desc, resultNode, new TypeRemapper(currentTypeMapping)); + final int markerShift = InlineCodegenUtil.calcMarkerShift(parameters, node); InlineAdapter lambdaInliner = new InlineAdapter(remappingMethodAdapter, parameters.getArgsSizeOnStack(), sourceMapper) { private AnonymousObjectGeneration anonymousObjectGen; @@ -217,7 +218,7 @@ public class MethodInliner { return; } - int valueParamShift = getNextLocalIndex();//NB: don't inline cause it changes + int valueParamShift = Math.max(getNextLocalIndex(), markerShift);//NB: don't inline cause it changes putStackValuesIntoLocals(info.getInvokeParamsWithoutCaptured(), valueParamShift, this, desc); addInlineMarker(this, true);