Set type of inliner's fake variable slots to int by storing 0

Otherwise, D8 drops the whole LVT.
 #KT-28309 Fixed
This commit is contained in:
Ilmir Usmanov
2018-12-11 19:57:28 +03:00
parent 55404ea00d
commit a107b5d6b6
3 changed files with 74 additions and 5 deletions
@@ -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,
@@ -0,0 +1,54 @@
// WITH_RUNTIME
class Range<T>(val min: T, val max: T)
class Sprite
class A {
private fun calcSpriteSizeRange(layoutSize: Int,
sprites: Map<Long, Sprite>,
minMargin: Int,
range: Range<Int>)
: Pair<Range<Int>, 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
@@ -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");