Restore last inline function call site line number on lambda inlining into @InlineOnly function

This commit is contained in:
Michael Bogdanov
2016-03-09 15:41:02 +03:00
parent 2e9075115b
commit c38f28fb08
8 changed files with 72 additions and 18 deletions
@@ -1773,6 +1773,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
public int getLastLineNumber() {
return myLastLineNumber;
}
private void doFinallyOnReturn(@NotNull Label afterReturnLabel) {
if(!blockStackElements.isEmpty()) {
BlockStackElement stackElement = blockStackElements.peek();
@@ -249,7 +249,8 @@ public class AnonymousObjectTransformer {
new InlineCallSiteInfo(
anonymousObjectGen.getOwnerInternalName(),
sourceNode.name,
isConstructor ? anonymousObjectGen.getNewConstructorDescriptor() : sourceNode.desc)
isConstructor ? anonymousObjectGen.getNewConstructorDescriptor() : sourceNode.desc),
null
);
InlineResult result = inliner.doInline(deferringVisitor, new LocalVarRemapper(parameters, 0), false, LabelOwner.NOT_APPLICABLE);
@@ -289,13 +289,14 @@ public class InlineCodegen extends CallGenerator {
InliningContext info = new RootInliningContext(
expressionMap, state, codegen.getInlineNameGenerator().subGenerator(jvmSignature.getAsmMethod().getName()),
codegen.getContext(), callElement, getInlineCallSiteInfo(), reifiedTypeInliner, typeParameterMappings,
AnnotationUtilKt.hasInlineOnlyAnnotation(functionDescriptor)
);
codegen.getContext(), callElement, getInlineCallSiteInfo(), reifiedTypeInliner, typeParameterMappings);
MethodInliner inliner = new MethodInliner(node, parameters, info, new FieldRemapper(null, null, parameters), isSameModule,
"Method inlining " + callElement.getText(),
createNestedSourceMapper(nodeAndSmap), info.getCallSiteInfo()); //with captured
MethodInliner inliner = new MethodInliner(
node, parameters, info, new FieldRemapper(null, null, parameters), isSameModule,
"Method inlining " + callElement.getText(),
createNestedSourceMapper(nodeAndSmap), info.getCallSiteInfo(),
AnnotationUtilKt.hasInlineOnlyAnnotation(functionDescriptor) ? new InlineOnlySmapSkipper(codegen) : null
); //with captured
LocalVarRemapper remapper = new LocalVarRemapper(parameters, initialFrameSize);
@@ -71,7 +71,7 @@ public class MethodInliner {
private int lambdasFinallyBlocks;
private final boolean skipSmap;
private final InlineOnlySmapSkipper inlineOnlySmapSkipper;
/*
*
@@ -88,7 +88,8 @@ public class MethodInliner {
boolean isSameModule,
@NotNull String errorPrefix,
@NotNull SourceMapper sourceMapper,
@NotNull InlineCallSiteInfo inlineCallSiteInfo
@NotNull InlineCallSiteInfo inlineCallSiteInfo,
@Nullable InlineOnlySmapSkipper smapSkipper //non null only for root
) {
this.node = node;
this.parameters = parameters;
@@ -100,7 +101,7 @@ public class MethodInliner {
this.inlineCallSiteInfo = inlineCallSiteInfo;
this.typeMapper = inliningContext.state.getTypeMapper();
this.result = InlineResult.create();
skipSmap = inliningContext instanceof RootInliningContext && ((RootInliningContext) inliningContext).skipSmap;
this.inlineOnlySmapSkipper = smapSkipper;
}
public InlineResult doInline(
@@ -162,7 +163,7 @@ public class MethodInliner {
final Iterator<AnonymousObjectGeneration> iterator = anonymousObjectGenerations.iterator();
final TypeRemapper remapper = TypeRemapper.createFrom(currentTypeMapping);
RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(
final RemappingMethodAdapter remappingMethodAdapter = new RemappingMethodAdapter(
resultNode.access,
resultNode.desc,
resultNode,
@@ -252,7 +253,7 @@ public class MethodInliner {
inliningContext.subInlineLambda(info),
newCapturedRemapper, true /*cause all calls in same module as lambda*/,
"Lambda inlining " + info.getLambdaClassType().getInternalName(),
mapper, inlineCallSiteInfo);
mapper, inlineCallSiteInfo, null);
LocalVarRemapper remapper = new LocalVarRemapper(lambdaParameters, valueParamShift);
InlineResult lambdaResult = inliner.doInline(this.mv, remapper, true, info, invokeCall.finallyDepthShift);//TODO add skipped this and receiver
@@ -266,6 +267,9 @@ public class MethodInliner {
setLambdaInlining(false);
addInlineMarker(this, false);
mapper.endMapping();
if (inlineOnlySmapSkipper != null) {
inlineOnlySmapSkipper.markCallSiteLineNumber(remappingMethodAdapter);
}
}
else if (isAnonymousConstructorCall(owner, name)) { //TODO add method
assert anonymousObjectGen != null : "<init> call not corresponds to new call" + owner + " " + name;
@@ -341,7 +345,7 @@ public class MethodInliner {
node.instructions.resetLabels();
MethodNode transformedNode = new MethodNode(InlineCodegenUtil.API, node.access, node.name, Type.getMethodDescriptor(returnType, allTypes), node.signature, null) {
private final boolean GENERATE_DEBUG_INFO = InlineCodegenUtil.GENERATE_SMAP && !skipSmap;
private final boolean GENERATE_DEBUG_INFO = InlineCodegenUtil.GENERATE_SMAP && inlineOnlySmapSkipper == null;
private final boolean isInliningLambda = nodeRemapper.isInsideInliningLambda();
@@ -28,7 +28,6 @@ public class RootInliningContext extends InliningContext {
public final CodegenContext startContext;
private final InlineCallSiteInfo inlineCallSiteInfo;
public final TypeParameterMappings typeParameterMappings;
public final boolean skipSmap;
public final KtElement callElement;
public RootInliningContext(
@@ -39,15 +38,13 @@ public class RootInliningContext extends InliningContext {
@NotNull KtElement callElement,
@NotNull InlineCallSiteInfo classNameToInline,
@NotNull ReifiedTypeInliner inliner,
@Nullable TypeParameterMappings typeParameterMappings,
boolean skipSmap
@Nullable TypeParameterMappings typeParameterMappings
) {
super(null, map, state, nameGenerator, TypeRemapper.createRoot(typeParameterMappings), inliner, false, false);
this.callElement = callElement;
this.startContext = startContext;
this.inlineCallSiteInfo = classNameToInline;
this.typeParameterMappings = typeParameterMappings;
this.skipSmap = skipSmap;
}
@Override
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -26,6 +27,8 @@ import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.MethodVisitor
val FunctionDescriptor.sourceFilePath: String
get() {
@@ -61,4 +64,17 @@ fun FunctionDescriptor.getClassFilePath(typeMapper: KotlinTypeMapper, cache: Inc
cache.getClassFilePath(className)
}
}
}
class InlineOnlySmapSkipper(codegen: ExpressionCodegen) {
val callLineNumber = codegen.lastLineNumber
fun markCallSiteLineNumber(mv: MethodVisitor) {
if (callLineNumber >= 0) {
val label = Label()
mv.visitLabel(label)
mv.visitLineNumber(callLineNumber, label)
}
}
}
+8
View File
@@ -2,6 +2,14 @@ LineBreakpoint created at inlineOnly.kt:5
!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
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
inlineOnly.kt:5
inlineOnly.kt:7
inlineOnly.kt:13
inlineOnly.kt:14
inlineOnly.kt:7
inlineOnly.kt:13
inlineOnly.kt:14
inlineOnly.kt:7
inlineOnly.kt:9
PrintStream.!EXT!
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
@@ -2,7 +2,30 @@ package inlineOnly
fun main(args: Array<String>) {
//Breakpoint!
println("OK")
myPrint("OK")
forEach { print2("123")}
println("OK") //stdlib test
}
fun print2(s: String){
val z = s;
}
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@kotlin.internal.InlineOnly
inline fun myPrint(s: String) {
val z = s;
}
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@kotlin.internal.InlineOnly
inline fun forEach(s: () -> Unit) {
for (i in 1..2) {
s()
}
}
// STEP_INTO: 9
// TRACING_FILTERS_ENABLED: false