JVM: move callSiteFile to InlineCallSiteInfo

This commit is contained in:
pyos
2021-06-08 13:21:04 +02:00
committed by max-kammerer
parent 6c1a5e1211
commit b136acb185
8 changed files with 24 additions and 49 deletions
@@ -9,7 +9,6 @@ import com.intellij.util.ArrayUtil
import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.coroutines.DEBUG_METADATA_ANNOTATION_ASM_TYPE import org.jetbrains.kotlin.codegen.coroutines.DEBUG_METADATA_ANNOTATION_ASM_TYPE
import org.jetbrains.kotlin.codegen.coroutines.isCoroutineSuperClass import org.jetbrains.kotlin.codegen.coroutines.isCoroutineSuperClass
import org.jetbrains.kotlin.codegen.coroutines.isResumeImplMethodName
import org.jetbrains.kotlin.codegen.inline.coroutines.CoroutineTransformer import org.jetbrains.kotlin.codegen.inline.coroutines.CoroutineTransformer
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
import org.jetbrains.kotlin.codegen.serialization.JvmCodegenStringTable import org.jetbrains.kotlin.codegen.serialization.JvmCodegenStringTable
@@ -27,6 +26,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.Companion.NO_ORIGIN import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.Companion.NO_ORIGIN
import org.jetbrains.org.objectweb.asm.* import org.jetbrains.org.objectweb.asm.*
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.commons.Method
import org.jetbrains.org.objectweb.asm.tree.* import org.jetbrains.org.objectweb.asm.tree.*
import java.util.* import java.util.*
@@ -272,7 +272,7 @@ class AnonymousObjectTransformer(
// Since $$forInline functions are not generated if retransformation is the last one (i.e. call site is not inline) // Since $$forInline functions are not generated if retransformation is the last one (i.e. call site is not inline)
// link to the function in OUTERCLASS field becomes invalid. However, since $$forInline function always has no-inline // link to the function in OUTERCLASS field becomes invalid. However, since $$forInline function always has no-inline
// companion without the suffix, use it. // companion without the suffix, use it.
visitor.visitOuterClass(info.ownerClassName, info.functionName?.removeSuffix(FOR_INLINE_SUFFIX), info.functionDesc) visitor.visitOuterClass(info.ownerClassName, info.method.name.removeSuffix(FOR_INLINE_SUFFIX), info.method.descriptor)
} }
private fun inlineMethodAndUpdateGlobalResult( private fun inlineMethodAndUpdateGlobalResult(
@@ -314,11 +314,10 @@ class AnonymousObjectTransformer(
SourceMapCopier(sourceMapper, sourceMap), SourceMapCopier(sourceMapper, sourceMap),
InlineCallSiteInfo( InlineCallSiteInfo(
transformationInfo.oldClassName, transformationInfo.oldClassName,
sourceNode.name, Method(sourceNode.name, if (isConstructor) transformationInfo.newConstructorDescriptor else sourceNode.desc),
if (isConstructor) transformationInfo.newConstructorDescriptor else sourceNode.desc,
inliningContext.callSiteInfo.isInlineOrInsideInline, inliningContext.callSiteInfo.isInlineOrInsideInline,
isSuspendFunctionOrLambda(sourceNode), inliningContext.callSiteInfo.file,
inliningContext.root.sourceCompilerForInline.inlineCallSiteInfo.lineNumber inliningContext.callSiteInfo.lineNumber
), null ), null
) )
@@ -328,12 +327,6 @@ class AnonymousObjectTransformer(
return result return result
} }
private fun isSuspendFunctionOrLambda(sourceNode: MethodNode): Boolean =
(sourceNode.desc.endsWith(";Lkotlin/coroutines/Continuation;)Ljava/lang/Object;") ||
sourceNode.desc.endsWith(";Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;")) &&
(CoroutineTransformer.findFakeContinuationConstructorClassName(sourceNode) != null ||
languageVersionSettings.isResumeImplMethodName(sourceNode.name.removeSuffix(FOR_INLINE_SUFFIX)))
private fun generateConstructorAndFields( private fun generateConstructorAndFields(
classBuilder: ClassBuilder, classBuilder: ClassBuilder,
allCapturedBuilder: ParametersBuilder, allCapturedBuilder: ParametersBuilder,
@@ -1,15 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.codegen.inline
class InlineCallSiteInfo(
val ownerClassName: String,
val functionName: String?,
val functionDesc: String?,
val isInlineOrInsideInline: Boolean,
val isSuspend: Boolean,
val lineNumber: Int
)
@@ -37,7 +37,7 @@ abstract class ObjectTransformer<out T : TransformationInfo>(@JvmField val trans
val classBuilder = state.factory.newVisitor( val classBuilder = state.factory.newVisitor(
JvmDeclarationOrigin.NO_ORIGIN, JvmDeclarationOrigin.NO_ORIGIN,
Type.getObjectType(transformationInfo.newClassName), Type.getObjectType(transformationInfo.newClassName),
inliningContext.root.sourceCompilerForInline.callsiteFile!! inliningContext.callSiteInfo.file!!
) )
return RemappingClassBuilder( return RemappingClassBuilder(
@@ -60,8 +60,6 @@ class PsiSourceCompilerForInline(
override val callElementText: String by lazy { callElement.text } override val callElementText: String by lazy { callElement.text }
override val callsiteFile by lazy { callElement.containingFile }
override val inlineCallSiteInfo: InlineCallSiteInfo override val inlineCallSiteInfo: InlineCallSiteInfo
get() { get() {
var context = codegen.getContext() var context = codegen.getContext()
@@ -78,10 +76,9 @@ class PsiSourceCompilerForInline(
val signature = codegen.state.typeMapper.mapSignatureSkipGeneric(context.functionDescriptor, context.contextKind) val signature = codegen.state.typeMapper.mapSignatureSkipGeneric(context.functionDescriptor, context.contextKind)
return InlineCallSiteInfo( return InlineCallSiteInfo(
parentCodegen.className, parentCodegen.className,
signature.asmMethod.name, signature.asmMethod,
signature.asmMethod.descriptor,
context.functionDescriptor.isInlineOrInsideInline(), context.functionDescriptor.isInlineOrInsideInline(),
context.functionDescriptor.isSuspend, callElement.containingFile,
CodegenUtil.getLineNumberForElement(callElement, false) ?: 0 CodegenUtil.getLineNumberForElement(callElement, false) ?: 0
) )
} }
@@ -23,6 +23,14 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.Method import org.jetbrains.org.objectweb.asm.commons.Method
import org.jetbrains.org.objectweb.asm.tree.MethodNode import org.jetbrains.org.objectweb.asm.tree.MethodNode
class InlineCallSiteInfo(
val ownerClassName: String,
val method: Method,
val isInlineOrInsideInline: Boolean,
val file: PsiFile?,
val lineNumber: Int
)
interface SourceCompilerForInline { interface SourceCompilerForInline {
val state: GenerationState val state: GenerationState
@@ -30,8 +38,6 @@ interface SourceCompilerForInline {
val callElementText: String val callElementText: String
val callsiteFile: PsiFile?
val inlineCallSiteInfo: InlineCallSiteInfo val inlineCallSiteInfo: InlineCallSiteInfo
val sourceMapper: SourceMapper val sourceMapper: SourceMapper
@@ -91,8 +91,8 @@ class CoroutineTransformer(
obtainClassBuilderForCoroutineState = { classBuilder }, obtainClassBuilderForCoroutineState = { classBuilder },
reportSuspensionPointInsideMonitor = { sourceCompilerForInline.reportSuspensionPointInsideMonitor(it) }, reportSuspensionPointInsideMonitor = { sourceCompilerForInline.reportSuspensionPointInsideMonitor(it) },
// TODO: this linenumbers might not be correct and since they are used only for step-over, check them. // TODO: this linenumbers might not be correct and since they are used only for step-over, check them.
lineNumber = sourceCompilerForInline.inlineCallSiteInfo.lineNumber, lineNumber = inliningContext.callSiteInfo.lineNumber,
sourceFile = sourceCompilerForInline.callsiteFile?.name ?: "", sourceFile = inliningContext.callSiteInfo.file?.name ?: "",
languageVersionSettings = state.languageVersionSettings, languageVersionSettings = state.languageVersionSettings,
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization, shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
containingClassInternalName = classBuilder.thisName, containingClassInternalName = classBuilder.thisName,
@@ -125,8 +125,8 @@ class CoroutineTransformer(
createNewMethodFrom(node, name), node.access, name, node.desc, null, null, createNewMethodFrom(node, name), node.access, name, node.desc, null, null,
obtainClassBuilderForCoroutineState = { (inliningContext as RegeneratedClassContext).continuationBuilders[continuationClassName]!! }, obtainClassBuilderForCoroutineState = { (inliningContext as RegeneratedClassContext).continuationBuilders[continuationClassName]!! },
reportSuspensionPointInsideMonitor = { sourceCompilerForInline.reportSuspensionPointInsideMonitor(it) }, reportSuspensionPointInsideMonitor = { sourceCompilerForInline.reportSuspensionPointInsideMonitor(it) },
lineNumber = sourceCompilerForInline.inlineCallSiteInfo.lineNumber, lineNumber = inliningContext.callSiteInfo.lineNumber,
sourceFile = sourceCompilerForInline.callsiteFile?.name ?: "", sourceFile = inliningContext.callSiteInfo.file?.name ?: "",
languageVersionSettings = state.languageVersionSettings, languageVersionSettings = state.languageVersionSettings,
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization, shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
containingClassInternalName = classBuilder.thisName, containingClassInternalName = classBuilder.thisName,
@@ -48,7 +48,7 @@ class IrInlineCodegen(
if (info.generateAssertField) { if (info.generateAssertField) {
// May be inlining code into `<clinit>`, in which case it's too late to modify the IR and // May be inlining code into `<clinit>`, in which case it's too late to modify the IR and
// `generateAssertFieldIfNeeded` will return a statement for which we need to emit bytecode. // `generateAssertFieldIfNeeded` will return a statement for which we need to emit bytecode.
val isClInit = info.callSiteInfo.functionName == "<clinit>" val isClInit = info.callSiteInfo.method.name == "<clinit>"
codegen.classCodegen.generateAssertFieldIfNeeded(isClInit)?.accept(codegen, BlockInfo())?.discard() codegen.classCodegen.generateAssertFieldIfNeeded(isClInit)?.accept(codegen, BlockInfo())?.discard()
} }
} }
@@ -46,19 +46,15 @@ class IrSourceCompilerForInline(
override val callElementText: String override val callElementText: String
get() = ir2string(callElement) get() = ir2string(callElement)
override val callsiteFile: PsiFile?
get() = codegen.irFunction.fileParent.getKtFile()
override val inlineCallSiteInfo: InlineCallSiteInfo override val inlineCallSiteInfo: InlineCallSiteInfo
get() { get() {
val root = generateSequence(codegen) { it.inlinedInto }.last() val root = generateSequence(codegen) { it.inlinedInto }.last()
return InlineCallSiteInfo( return InlineCallSiteInfo(
root.classCodegen.type.internalName, root.classCodegen.type.internalName,
root.signature.asmMethod.name, root.signature.asmMethod,
root.signature.asmMethod.descriptor,
root.irFunction.isInlineOrInsideInline(), root.irFunction.isInlineOrInsideInline(),
root.irFunction.isSuspend, root.irFunction.fileParent.getKtFile(),
findElement()?.let { CodegenUtil.getLineNumberForElement(it, false) } ?: 0 callElement.psiElement?.let { CodegenUtil.getLineNumberForElement(it, false) } ?: 0
) )
} }
@@ -141,8 +137,6 @@ class IrSourceCompilerForInline(
.at(callElement.symbol.owner as IrDeclaration) .at(callElement.symbol.owner as IrDeclaration)
.report(SUSPENSION_POINT_INSIDE_MONITOR, stackTraceElement) .report(SUSPENSION_POINT_INSIDE_MONITOR, stackTraceElement)
} }
private fun findElement() = callElement.psiElement as? KtElement
} }
private tailrec fun IrDeclaration.isInlineOrInsideInline(): Boolean { private tailrec fun IrDeclaration.isInlineOrInsideInline(): Boolean {