JVM: do not write trivial SMAPs to classes outside inline funs

where trivial == those that map the file to itself.
This commit is contained in:
pyos
2020-04-23 14:42:22 +02:00
committed by max-kammerer
parent a04aeeb4e1
commit d17a18f96d
30 changed files with 121 additions and 204 deletions
@@ -54,7 +54,6 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.CallableReferenceUtilKt.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.initDefaultSourceMappingIfNeeded;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
@@ -170,7 +169,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
superInterfaceAsmTypes
);
initDefaultSourceMappingIfNeeded(context, this, state);
initDefaultSourceMappingIfNeeded();
v.visitSource(element.getContainingFile().getName(), null);
}
@@ -68,7 +68,6 @@ import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isNonGenericToArray;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.getDelegatedLocalVariableMetadata;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.initDefaultSourceMappingIfNeeded;
import static org.jetbrains.kotlin.load.java.JvmAbi.*;
import static org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_GET;
import static org.jetbrains.kotlin.resolve.BindingContext.INDEXED_LVALUE_SET;
@@ -228,7 +227,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
v.visitSource(myClass.getContainingKtFile().getName(), null);
initDefaultSourceMappingIfNeeded(context, this, state);
initDefaultSourceMappingIfNeeded();
writeEnclosingMethod();
@@ -88,6 +88,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
private NameGenerator inlineNameGenerator;
private boolean jvmAssertFieldGenerated;
private boolean alwaysWriteSourceMap;
private SourceMapper sourceMapper;
public MemberCodegen(
@@ -182,8 +183,8 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
writeInnerClasses();
if (sourceMapper != null) {
v.visitSMAP(sourceMapper, !state.getLanguageVersionSettings().supportsFeature(LanguageFeature.CorrectSourceMappingSyntax));
if (alwaysWriteSourceMap || (sourceMapper != null && !sourceMapper.isTrivial())) {
v.visitSMAP(getOrCreateSourceMapper(), !state.getLanguageVersionSettings().supportsFeature(LanguageFeature.CorrectSourceMappingSyntax));
}
v.done();
@@ -730,6 +731,19 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
return sourceMapper;
}
protected void initDefaultSourceMappingIfNeeded() {
if (state.isInlineDisabled()) return;
CodegenContext parentContext = context.getParentContext();
while (parentContext != null) {
if (parentContext.isInlineMethodContext()) {
alwaysWriteSourceMap = true;
return;
}
parentContext = parentContext.getParentContext();
}
}
protected void generateConstInstance(@NotNull Type thisAsmType, @NotNull Type fieldAsmType) {
v.newField(
JvmDeclarationOriginKt.OtherOriginFromPure(element), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD,
@@ -95,6 +95,9 @@ class SourceMapper(val sourceInfo: SourceInfo?) {
}
}
val isTrivial: Boolean
get() = maxUsedValue == 0 || maxUsedValue == sourceInfo?.linesInFile
private fun getOrRegisterNewSource(name: String, path: String): FileMapping =
fileMappings.getOrPut(name to path) { FileMapping(name, path) }
@@ -565,22 +565,6 @@ class InlineOnlySmapSkipper(codegen: BaseExpressionCodegen) {
}
}
fun initDefaultSourceMappingIfNeeded(
context: CodegenContext<*>, codegen: MemberCodegen<*>, state: GenerationState
) {
if (state.isInlineDisabled) return
var parentContext: CodegenContext<*>? = context.parentContext
while (parentContext != null) {
if (parentContext.isInlineMethodContext) {
//just init default one to one mapping
codegen.orCreateSourceMapper
break
}
parentContext = parentContext.parentContext
}
}
fun MethodNode.preprocessSuspendMarkers(forInline: Boolean, keepFakeContinuation: Boolean = true) {
if (instructions.first == null) return
if (!keepFakeContinuation) {
@@ -89,8 +89,6 @@ abstract class ClassCodegen protected constructor(
)
}
internal var writeSourceMap: Boolean = withinInline
private var regeneratedObjectNameGenerators = mutableMapOf<String, NameGenerator>()
fun getRegeneratedObjectNameGenerator(function: IrFunction): NameGenerator {
@@ -145,7 +143,7 @@ abstract class ClassCodegen protected constructor(
generateInnerAndOuterClasses()
if (writeSourceMap) {
if (withinInline || !smap.isTrivial) {
visitor.visitSMAP(smap, !context.state.languageVersionSettings.supportsFeature(LanguageFeature.CorrectSourceMappingSyntax))
} else {
visitor.visitSource(smap.sourceInfo!!.source, null)
@@ -86,7 +86,7 @@ class IrSourceCompilerForInline(
}
override val lazySourceMapper: SourceMapper
get() = codegen.smap.also { codegen.classCodegen.writeSourceMap = true }
get() = codegen.smap
override fun generateLambdaBody(lambdaInfo: ExpressionLambda): SMAPAndMethodNode =
FunctionCodegen((lambdaInfo as IrExpressionLambdaImpl).function, codegen.classCodegen, codegen).generate()
-11
View File
@@ -37,17 +37,6 @@ fun box(): String {
}
// FILE: 1.smap
//TODO maybe do smth with default method body mapping
SMAP
1.kt
Kotlin
*S Kotlin
*F
+ 1 1.kt
test/_1Kt
*L
1#1,26:1
*E
// FILE: 2.smap
@@ -83,17 +83,6 @@ test/_1Kt$inlineMe1$2$run$1
*E
// FILE: 2.smap
SMAP
2.kt
Kotlin
*S Kotlin
*F
+ 1 2.kt
_2Kt$builder$1
*L
1#1,29:1
*E
SMAP
2.kt
Kotlin
@@ -15,18 +15,6 @@ fun box(): String {
}
// FILE: 1.smap
//TODO maybe do smth with default method body mapping
SMAP
1.kt
Kotlin
*S Kotlin
*F
+ 1 1.kt
test/_1Kt
*L
1#1,9:1
*E
SMAP
1.kt
Kotlin
@@ -44,17 +44,6 @@ fun box(): String {
}
// FILE: 1.smap
SMAP
1.kt
Kotlin
*S Kotlin
*F
+ 1 1.kt
test/_1Kt
*L
1#1,39:1
*E
SMAP
1.kt
Kotlin
@@ -46,17 +46,6 @@ fun box(): String {
}
// FILE: 1.smap
SMAP
1.kt
Kotlin
*S Kotlin
*F
+ 1 1.kt
test/_1Kt
*L
1#1,39:1
*E
SMAP
1.kt
Kotlin
@@ -82,17 +82,6 @@ fun box(): String {
}
// FILE: 1.smap
SMAP
1.kt
Kotlin
*S Kotlin
*F
+ 1 1.kt
test/_1Kt
*L
1#1,75:1
*E
SMAP
1.kt
Kotlin
@@ -45,17 +45,6 @@ fun box(): String {
}
// FILE: 1.smap
SMAP
1.kt
Kotlin
*S Kotlin
*F
+ 1 1.kt
test/_1Kt
*L
1#1,40:1
*E
SMAP
1.kt
Kotlin
@@ -47,17 +47,6 @@ fun box(): String {
}
// FILE: 1.smap
SMAP
1.kt
Kotlin
*S Kotlin
*F
+ 1 1.kt
test/_1Kt
*L
1#1,40:1
*E
SMAP
1.kt
Kotlin
@@ -45,17 +45,6 @@ fun box(): String {
}
// FILE: 1.smap
SMAP
1.kt
Kotlin
*S Kotlin
*F
+ 1 1.kt
test/_1Kt
*L
1#1,38:1
*E
SMAP
1.kt
Kotlin
@@ -19,18 +19,6 @@ fun box(): String {
}
// FILE: 1.smap
//TODO maybe do smth with default method body mapping
SMAP
1.kt
Kotlin
*S Kotlin
*F
+ 1 1.kt
test/_1Kt
*L
1#1,13:1
*E
SMAP
1.kt
Kotlin
@@ -17,18 +17,6 @@ fun box(): String {
}
// FILE: 1.smap
//TODO maybe do smth with default method body mapping
SMAP
1.kt
Kotlin
*S Kotlin
*F
+ 1 1.kt
test/_1Kt
*L
1#1,11:1
*E
SMAP
1.kt
Kotlin
@@ -43,17 +43,6 @@ fun box(): String {
}
// FILE: 1.smap
SMAP
1.kt
Kotlin
*S Kotlin
*F
+ 1 1.kt
test/_1Kt
*L
1#1,38:1
*E
SMAP
1.kt
Kotlin
@@ -13,14 +13,3 @@ fun box(): String {
}
// FILE: 2.smap
SMAP
2.kt
Kotlin
*S Kotlin
*F
+ 1 2.kt
_2Kt
*L
1#1,7:1
*E
@@ -18,14 +18,3 @@ fun box(): String {
}
// FILE: 2.smap
SMAP
2.kt
Kotlin
*S Kotlin
*F
+ 1 2.kt
_2Kt
*L
1#1,8:1
*E
@@ -0,0 +1,21 @@
// FILE: 1.kt
package test
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@kotlin.internal.InlineOnly
inline fun <T, R> T.myLet(block: (T) -> R) = block(this)
// FILE: 2.kt
import test.*
fun box(): String {
// should not have any line numbers
val k = "".myLet {
it + "K"
}
return "O".myLet(fun (it: String): String {
return it + k
})
}
// FILE: 2.smap
@@ -0,0 +1,16 @@
// FILE: 1.kt
package test
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
@kotlin.internal.InlineOnly
inline fun <T, R> T.myLet(block: (T) -> R) = block(this)
// FILE: 2.kt
import test.*
fun box(): String {
val k = "".myLet { it + "K" }
return "O".myLet(fun (it: String): String { return it + k })
}
// FILE: 2.smap
@@ -3522,6 +3522,16 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
public void testReifiedProperty() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/reifiedProperty.kt");
}
@TestMetadata("stdlibInlineOnly.kt")
public void testStdlibInlineOnly() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/stdlibInlineOnly.kt");
}
@TestMetadata("stdlibInlineOnlyOneLine.kt")
public void testStdlibInlineOnlyOneLine() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/stdlibInlineOnlyOneLine.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/smap/newsmap")
@@ -3522,6 +3522,16 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
public void testReifiedProperty() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/reifiedProperty.kt");
}
@TestMetadata("stdlibInlineOnly.kt")
public void testStdlibInlineOnly() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/stdlibInlineOnly.kt");
}
@TestMetadata("stdlibInlineOnlyOneLine.kt")
public void testStdlibInlineOnlyOneLine() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/stdlibInlineOnlyOneLine.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/smap/newsmap")
@@ -3522,6 +3522,16 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli
public void testReifiedProperty() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/reifiedProperty.kt");
}
@TestMetadata("stdlibInlineOnly.kt")
public void testStdlibInlineOnly() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/stdlibInlineOnly.kt");
}
@TestMetadata("stdlibInlineOnlyOneLine.kt")
public void testStdlibInlineOnlyOneLine() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/stdlibInlineOnlyOneLine.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/smap/newsmap")
@@ -3522,6 +3522,16 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC
public void testReifiedProperty() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/reifiedProperty.kt");
}
@TestMetadata("stdlibInlineOnly.kt")
public void testStdlibInlineOnly() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/stdlibInlineOnly.kt");
}
@TestMetadata("stdlibInlineOnlyOneLine.kt")
public void testStdlibInlineOnlyOneLine() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/stdlibInlineOnlyOneLine.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/smap/newsmap")
@@ -438,32 +438,12 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
compileKotlin("source.kt", tmpdir, listOf(tmpdir))
var debugInfo: String? = null
val resultFile = File(tmpdir.absolutePath, "test/B.class")
ClassReader(resultFile.readBytes()).accept(object : ClassVisitor(Opcodes.API_VERSION) {
override fun visitSource(source: String?, debug: String?) {
debugInfo = debug
assertEquals(null, debug)
}
}, 0)
val expected = """
SMAP
source.kt
Kotlin
*S Kotlin
*F
+ 1 source.kt
test/B
*L
1#1,13:1
*E
""".trimIndent() + "\n"
if (GENERATE_SMAP) {
assertEquals(expected, debugInfo)
} else {
assertEquals(null, debugInfo)
}
}
/* Regression test for KT-37107: compile against .class file without any constructors. */
@@ -3122,6 +3122,16 @@ public class IrJsCodegenInlineTestGenerated extends AbstractIrJsCodegenInlineTes
public void testNoSmapWithProperty() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/noSmapWithProperty.kt");
}
@TestMetadata("stdlibInlineOnly.kt")
public void testStdlibInlineOnly() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/stdlibInlineOnly.kt");
}
@TestMetadata("stdlibInlineOnlyOneLine.kt")
public void testStdlibInlineOnlyOneLine() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/stdlibInlineOnlyOneLine.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/smap/newsmap")
@@ -3122,6 +3122,16 @@ public class JsCodegenInlineTestGenerated extends AbstractJsCodegenInlineTest {
public void testNoSmapWithProperty() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/noSmapWithProperty.kt");
}
@TestMetadata("stdlibInlineOnly.kt")
public void testStdlibInlineOnly() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/stdlibInlineOnly.kt");
}
@TestMetadata("stdlibInlineOnlyOneLine.kt")
public void testStdlibInlineOnlyOneLine() throws Exception {
runTest("compiler/testData/codegen/boxInline/smap/inlineOnly/stdlibInlineOnlyOneLine.kt");
}
}
@TestMetadata("compiler/testData/codegen/boxInline/smap/newsmap")