Skip to content

Commit c38f28f

Browse files
author
Michael Bogdanov
committed
Restore last inline function call site line number on lambda inlining into @InlineOnly function
1 parent 2e90751 commit c38f28f

File tree

8 files changed

+73
-19
lines changed

8 files changed

+73
-19
lines changed

compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,6 +1773,10 @@ public void markLineNumberAfterInlineIfNeeded() {
17731773
}
17741774
}
17751775

1776+
public int getLastLineNumber() {
1777+
return myLastLineNumber;
1778+
}
1779+
17761780
private void doFinallyOnReturn(@NotNull Label afterReturnLabel) {
17771781
if(!blockStackElements.isEmpty()) {
17781782
BlockStackElement stackElement = blockStackElements.peek();

compiler/backend/src/org/jetbrains/kotlin/codegen/inline/AnonymousObjectTransformer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,8 @@ private InlineResult inlineMethod(
249249
new InlineCallSiteInfo(
250250
anonymousObjectGen.getOwnerInternalName(),
251251
sourceNode.name,
252-
isConstructor ? anonymousObjectGen.getNewConstructorDescriptor() : sourceNode.desc)
252+
isConstructor ? anonymousObjectGen.getNewConstructorDescriptor() : sourceNode.desc),
253+
null
253254
);
254255

255256
InlineResult result = inliner.doInline(deferringVisitor, new LocalVarRemapper(parameters, 0), false, LabelOwner.NOT_APPLICABLE);

compiler/backend/src/org/jetbrains/kotlin/codegen/inline/InlineCodegen.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,13 +289,14 @@ private InlineResult inlineCall(SMAPAndMethodNode nodeAndSmap) {
289289

290290
InliningContext info = new RootInliningContext(
291291
expressionMap, state, codegen.getInlineNameGenerator().subGenerator(jvmSignature.getAsmMethod().getName()),
292-
codegen.getContext(), callElement, getInlineCallSiteInfo(), reifiedTypeInliner, typeParameterMappings,
293-
AnnotationUtilKt.hasInlineOnlyAnnotation(functionDescriptor)
294-
);
295-
296-
MethodInliner inliner = new MethodInliner(node, parameters, info, new FieldRemapper(null, null, parameters), isSameModule,
297-
"Method inlining " + callElement.getText(),
298-
createNestedSourceMapper(nodeAndSmap), info.getCallSiteInfo()); //with captured
292+
codegen.getContext(), callElement, getInlineCallSiteInfo(), reifiedTypeInliner, typeParameterMappings);
293+
294+
MethodInliner inliner = new MethodInliner(
295+
node, parameters, info, new FieldRemapper(null, null, parameters), isSameModule,
296+
"Method inlining " + callElement.getText(),
297+
createNestedSourceMapper(nodeAndSmap), info.getCallSiteInfo(),
298+
AnnotationUtilKt.hasInlineOnlyAnnotation(functionDescriptor) ? new InlineOnlySmapSkipper(codegen) : null
299+
); //with captured
299300

300301
LocalVarRemapper remapper = new LocalVarRemapper(parameters, initialFrameSize);
301302

compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public class MethodInliner {
7171

7272
private int lambdasFinallyBlocks;
7373

74-
private final boolean skipSmap;
74+
private final InlineOnlySmapSkipper inlineOnlySmapSkipper;
7575

7676
/*
7777
*
@@ -88,7 +88,8 @@ public MethodInliner(
8888
boolean isSameModule,
8989
@NotNull String errorPrefix,
9090
@NotNull SourceMapper sourceMapper,
91-
@NotNull InlineCallSiteInfo inlineCallSiteInfo
91+
@NotNull InlineCallSiteInfo inlineCallSiteInfo,
92+
@Nullable InlineOnlySmapSkipper smapSkipper //non null only for root
9293
) {
9394
this.node = node;
9495
this.parameters = parameters;
@@ -100,7 +101,7 @@ public MethodInliner(
100101
this.inlineCallSiteInfo = inlineCallSiteInfo;
101102
this.typeMapper = inliningContext.state.getTypeMapper();
102103
this.result = InlineResult.create();
103-
skipSmap = inliningContext instanceof RootInliningContext && ((RootInliningContext) inliningContext).skipSmap;
104+
this.inlineOnlySmapSkipper = smapSkipper;
104105
}
105106

106107
public InlineResult doInline(
@@ -162,7 +163,7 @@ private MethodNode doInline(final MethodNode node) {
162163
final Iterator<AnonymousObjectGeneration> iterator = anonymousObjectGenerations.iterator();
163164

164165
final TypeRemapper remapper = TypeRemapper.createFrom(currentTypeMapping);
165-
RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(
166+
final RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(
166167
resultNode.access,
167168
resultNode.desc,
168169
resultNode,
@@ -252,7 +253,7 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc,
252253
inliningContext.subInlineLambda(info),
253254
newCapturedRemapper, true /*cause all calls in same module as lambda*/,
254255
"Lambda inlining " + info.getLambdaClassType().getInternalName(),
255-
mapper, inlineCallSiteInfo);
256+
mapper, inlineCallSiteInfo, null);
256257

257258
LocalVarRemapper remapper = new LocalVarRemapper(lambdaParameters, valueParamShift);
258259
InlineResult lambdaResult = inliner.doInline(this.mv, remapper, true, info, invokeCall.finallyDepthShift);//TODO add skipped this and receiver
@@ -266,6 +267,9 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc,
266267
setLambdaInlining(false);
267268
addInlineMarker(this, false);
268269
mapper.endMapping();
270+
if (inlineOnlySmapSkipper != null) {
271+
inlineOnlySmapSkipper.markCallSiteLineNumber(remappingMethodAdapter);
272+
}
269273
}
270274
else if (isAnonymousConstructorCall(owner, name)) { //TODO add method
271275
assert anonymousObjectGen != null : "<init> call not corresponds to new call" + owner + " " + name;
@@ -341,7 +345,7 @@ public MethodNode prepareNode(@NotNull MethodNode node, int finallyDeepShift) {
341345
node.instructions.resetLabels();
342346
MethodNode transformedNode = new MethodNode(InlineCodegenUtil.API, node.access, node.name, Type.getMethodDescriptor(returnType, allTypes), node.signature, null) {
343347

344-
private final boolean GENERATE_DEBUG_INFO = InlineCodegenUtil.GENERATE_SMAP && !skipSmap;
348+
private final boolean GENERATE_DEBUG_INFO = InlineCodegenUtil.GENERATE_SMAP && inlineOnlySmapSkipper == null;
345349

346350
private final boolean isInliningLambda = nodeRemapper.isInsideInliningLambda();
347351

compiler/backend/src/org/jetbrains/kotlin/codegen/inline/RootInliningContext.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ public class RootInliningContext extends InliningContext {
2828
public final CodegenContext startContext;
2929
private final InlineCallSiteInfo inlineCallSiteInfo;
3030
public final TypeParameterMappings typeParameterMappings;
31-
public final boolean skipSmap;
3231
public final KtElement callElement;
3332

3433
public RootInliningContext(
@@ -39,15 +38,13 @@ public RootInliningContext(
3938
@NotNull KtElement callElement,
4039
@NotNull InlineCallSiteInfo classNameToInline,
4140
@NotNull ReifiedTypeInliner inliner,
42-
@Nullable TypeParameterMappings typeParameterMappings,
43-
boolean skipSmap
41+
@Nullable TypeParameterMappings typeParameterMappings
4442
) {
4543
super(null, map, state, nameGenerator, TypeRemapper.createRoot(typeParameterMappings), inliner, false, false);
4644
this.callElement = callElement;
4745
this.startContext = startContext;
4846
this.inlineCallSiteInfo = classNameToInline;
4947
this.typeParameterMappings = typeParameterMappings;
50-
this.skipSmap = skipSmap;
5148
}
5249

5350
@Override

compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.jetbrains.kotlin.codegen.inline
1818

19+
import org.jetbrains.kotlin.codegen.ExpressionCodegen
1920
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
2021
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
2122
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -26,6 +27,8 @@ import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
2627
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
2728
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
2829
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
30+
import org.jetbrains.org.objectweb.asm.Label
31+
import org.jetbrains.org.objectweb.asm.MethodVisitor
2932

3033
val FunctionDescriptor.sourceFilePath: String
3134
get() {
@@ -61,4 +64,17 @@ fun FunctionDescriptor.getClassFilePath(typeMapper: KotlinTypeMapper, cache: Inc
6164
cache.getClassFilePath(className)
6265
}
6366
}
67+
}
68+
69+
class InlineOnlySmapSkipper(codegen: ExpressionCodegen) {
70+
71+
val callLineNumber = codegen.lastLineNumber
72+
73+
fun markCallSiteLineNumber(mv: MethodVisitor) {
74+
if (callLineNumber >= 0) {
75+
val label = Label()
76+
mv.visitLabel(label)
77+
mv.visitLineNumber(callLineNumber, label)
78+
}
79+
}
6480
}

idea/testData/debugger/tinyApp/outs/inlineOnly.out

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ LineBreakpoint created at inlineOnly.kt:5
22
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! inlineOnly.InlineOnlyKt
33
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
44
inlineOnly.kt:5
5+
inlineOnly.kt:7
6+
inlineOnly.kt:13
7+
inlineOnly.kt:14
8+
inlineOnly.kt:7
9+
inlineOnly.kt:13
10+
inlineOnly.kt:14
11+
inlineOnly.kt:7
12+
inlineOnly.kt:9
513
PrintStream.!EXT!
614
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
715

idea/testData/debugger/tinyApp/src/stepping/stepInto/inlineOnly.kt

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,30 @@ package inlineOnly
22

33
fun main(args: Array<String>) {
44
//Breakpoint!
5-
println("OK")
5+
myPrint("OK")
6+
7+
forEach { print2("123")}
8+
9+
println("OK") //stdlib test
10+
}
11+
12+
fun print2(s: String){
13+
val z = s;
14+
}
15+
16+
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
17+
@kotlin.internal.InlineOnly
18+
inline fun myPrint(s: String) {
19+
val z = s;
20+
}
21+
22+
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
23+
@kotlin.internal.InlineOnly
24+
inline fun forEach(s: () -> Unit) {
25+
for (i in 1..2) {
26+
s()
27+
}
628
}
729

30+
// STEP_INTO: 9
831
// TRACING_FILTERS_ENABLED: false

0 commit comments

Comments
 (0)