JVM: remove some FunctionDescriptors from SourceCompilerForInline

This commit is contained in:
pyos
2021-05-25 19:59:45 +02:00
committed by max-kammerer
parent a24ad233ee
commit 4c7eb815fc
6 changed files with 47 additions and 81 deletions
@@ -2950,12 +2950,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
bindingContext, state bindingContext, state
); );
PsiSourceCompilerForInline sourceCompiler = new PsiSourceCompilerForInline(this, callElement);
FunctionDescriptor functionDescriptor = FunctionDescriptor functionDescriptor =
InlineUtil.isArrayConstructorWithLambda(original) InlineUtil.isArrayConstructorWithLambda(original)
? FictitiousArrayConstructor.create((ConstructorDescriptor) original) : original.getOriginal(); ? FictitiousArrayConstructor.create((ConstructorDescriptor) original) : original.getOriginal();
PsiSourceCompilerForInline sourceCompiler = new PsiSourceCompilerForInline(this, callElement, functionDescriptor);
sourceCompiler.initializeInlineFunctionContext(functionDescriptor);
JvmMethodSignature signature = typeMapper.mapSignatureWithGeneric(functionDescriptor, sourceCompiler.getContextKind()); JvmMethodSignature signature = typeMapper.mapSignatureWithGeneric(functionDescriptor, sourceCompiler.getContextKind());
if (signature.getAsmMethod().getName().contains("-") && if (signature.getAsmMethod().getName().contains("-") &&
!state.getConfiguration().getBoolean(JVMConfigurationKeys.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME) !state.getConfiguration().getBoolean(JVMConfigurationKeys.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME)
@@ -58,8 +58,6 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
private val initialFrameSize = codegen.frameMap.currentSize private val initialFrameSize = codegen.frameMap.currentSize
private val isSameModule: Boolean = sourceCompiler.isCallInsideSameModuleAsDeclared(functionDescriptor)
protected val invocationParamBuilder = ParametersBuilder.newBuilder() protected val invocationParamBuilder = ParametersBuilder.newBuilder()
protected val expressionMap = linkedMapOf<Int, FunctionalArgument>() protected val expressionMap = linkedMapOf<Int, FunctionalArgument>()
@@ -214,7 +212,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
val sourceInfo = sourceMapper.sourceInfo!! val sourceInfo = sourceMapper.sourceInfo!!
val callSite = SourcePosition(codegen.lastLineNumber, sourceInfo.sourceFileName!!, sourceInfo.pathOrCleanFQN) val callSite = SourcePosition(codegen.lastLineNumber, sourceInfo.sourceFileName!!, sourceInfo.pathOrCleanFQN)
val inliner = MethodInliner( val inliner = MethodInliner(
node, parameters, info, FieldRemapper(null, null, parameters), isSameModule, node, parameters, info, FieldRemapper(null, null, parameters), sourceCompiler.isCallInsideSameModuleAsCallee,
"Method inlining " + sourceCompiler.callElementText, "Method inlining " + sourceCompiler.callElementText,
SourceMapCopier(sourceMapper, nodeAndSmap.classSMAP, callSite), SourceMapCopier(sourceMapper, nodeAndSmap.classSMAP, callSite),
info.callSiteInfo, if (functionDescriptor.isInlineOnly()) InlineOnlySmapSkipper(codegen) else null, info.callSiteInfo, if (functionDescriptor.isInlineOnly()) InlineOnlySmapSkipper(codegen) else null,
@@ -234,7 +232,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
generateAndInsertFinallyBlocks( generateAndInsertFinallyBlocks(
adapter, infos, (remapper.remap(parameters.argsSizeOnStack + 1).value as StackValue.Local).index adapter, infos, (remapper.remap(parameters.argsSizeOnStack + 1).value as StackValue.Local).index
) )
if (!sourceCompiler.isFinallyMarkerRequired()) { if (!sourceCompiler.isFinallyMarkerRequired) {
removeFinallyMarkers(adapter) removeFinallyMarkers(adapter)
} }
@@ -456,7 +454,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor) val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
if (!isBuiltInArrayIntrinsic(functionDescriptor) && !descriptorIsDeserialized(directMember)) { if (!isBuiltInArrayIntrinsic(functionDescriptor) && !descriptorIsDeserialized(directMember)) {
val node = sourceCompiler.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod) val node = sourceCompiler.compileInlineFunction(jvmSignature, callDefault, asmMethod)
node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false) node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
return node return node
} }
@@ -30,27 +30,30 @@ import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type 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
import kotlin.properties.Delegates
class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, override val callElement: KtElement) : class PsiSourceCompilerForInline(
SourceCompilerForInline { private val codegen: ExpressionCodegen,
override val callElement: KtElement,
private val functionDescriptor: FunctionDescriptor
) : SourceCompilerForInline {
override val state
get() = codegen.state
override val state = codegen.state private val additionalInnerClasses = mutableListOf<ClassDescriptor>()
private var context by Delegates.notNull<CodegenContext<*>>() private val context = getContext(
functionDescriptor,
private var additionalInnerClasses = mutableListOf<ClassDescriptor>() functionDescriptor,
codegen.state,
DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)?.containingFile as? KtFile,
additionalInnerClasses
)
override val lookupLocation = KotlinLookupLocation(callElement) override val lookupLocation = KotlinLookupLocation(callElement)
override val callElementText: String by lazy { callElement.text }
override val callElementText: String by lazy { override val callsiteFile by lazy { callElement.containingFile }
callElement.text
}
override val callsiteFile by lazy {
callElement.containingFile
}
override val contextKind override val contextKind
get () = context.contextKind get () = context.contextKind
@@ -211,22 +214,18 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
} }
} }
override fun doCreateMethodNodeFromSource( override fun compileInlineFunction(jvmSignature: JvmMethodSignature, callDefault: Boolean, asmMethod: Method): SMAPAndMethodNode {
callableDescriptor: FunctionDescriptor, val element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)
jvmSignature: JvmMethodSignature,
callDefault: Boolean,
asmMethod: Method
): SMAPAndMethodNode {
val element = DescriptorToSourceUtils.descriptorToDeclaration(callableDescriptor)
if (!(element is KtNamedFunction || element is KtPropertyAccessor)) { if (!(element is KtNamedFunction || element is KtPropertyAccessor)) {
throw IllegalStateException("Couldn't find declaration for function $callableDescriptor") throw IllegalStateException("Couldn't find declaration for function $functionDescriptor")
} }
val inliningFunction = element as KtDeclarationWithBody? val inliningFunction = element as KtDeclarationWithBody?
val node = MethodNode( val node = MethodNode(
Opcodes.API_VERSION, Opcodes.API_VERSION,
DescriptorAsmUtil.getMethodAsmFlags(callableDescriptor, context.contextKind, state) or if (callDefault) Opcodes.ACC_STATIC else 0, DescriptorAsmUtil.getMethodAsmFlags(functionDescriptor, context.contextKind, state) or
if (callDefault) Opcodes.ACC_STATIC else 0,
asmMethod.name, asmMethod.name,
asmMethod.descriptor, null, null asmMethod.descriptor, null, null
) )
@@ -234,10 +233,10 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
//for maxLocals calculation //for maxLocals calculation
val maxCalcAdapter = wrapWithMaxLocalCalc(node) val maxCalcAdapter = wrapWithMaxLocalCalc(node)
val parentContext = context.parentContext ?: error("Context has no parent: $context") val parentContext = context.parentContext ?: error("Context has no parent: $context")
val methodContext = parentContext.intoFunction(callableDescriptor) val methodContext = parentContext.intoFunction(functionDescriptor)
val smap = if (callDefault) { val smap = if (callDefault) {
val implementationOwner = state.typeMapper.mapImplementationOwner(callableDescriptor) val implementationOwner = state.typeMapper.mapImplementationOwner(functionDescriptor)
val parentCodegen = FakeMemberCodegen( val parentCodegen = FakeMemberCodegen(
codegen.parentCodegen, inliningFunction!!, methodContext.parentContext as FieldOwnerContext<*>, codegen.parentCodegen, inliningFunction!!, methodContext.parentContext as FieldOwnerContext<*>,
implementationOwner.internalName, implementationOwner.internalName,
@@ -245,15 +244,15 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
false false
) )
if (element !is KtNamedFunction) { if (element !is KtNamedFunction) {
throw IllegalStateException("Property accessors with default parameters not supported $callableDescriptor") throw IllegalStateException("Property accessors with default parameters not supported $functionDescriptor")
} }
FunctionCodegen.generateDefaultImplBody( FunctionCodegen.generateDefaultImplBody(
methodContext, callableDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT, methodContext, functionDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
inliningFunction as KtNamedFunction?, parentCodegen, asmMethod inliningFunction as KtNamedFunction?, parentCodegen, asmMethod
) )
SMAP(parentCodegen.orCreateSourceMapper.resultMappings) SMAP(parentCodegen.orCreateSourceMapper.resultMappings)
} else { } else {
generateMethodBody(maxCalcAdapter, callableDescriptor, methodContext, inliningFunction!!, jvmSignature, null) generateMethodBody(maxCalcAdapter, functionDescriptor, methodContext, inliningFunction!!, jvmSignature, null)
} }
maxCalcAdapter.visitMaxs(-1, -1) maxCalcAdapter.visitMaxs(-1, -1)
maxCalcAdapter.visitEnd() maxCalcAdapter.visitEnd()
@@ -277,12 +276,11 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
it.addBlockStackElementsForNonLocalReturns(codegen.blockStackElements, curFinallyDepth) it.addBlockStackElementsForNonLocalReturns(codegen.blockStackElements, curFinallyDepth)
} }
override fun isCallInsideSameModuleAsDeclared(functionDescriptor: FunctionDescriptor): Boolean { override val isCallInsideSameModuleAsCallee: Boolean
return JvmCodegenUtil.isCallInsideSameModuleAsDeclared(functionDescriptor, codegen.getContext(), codegen.state.outDirectory) get() = JvmCodegenUtil.isCallInsideSameModuleAsDeclared(functionDescriptor, codegen.getContext(), codegen.state.outDirectory)
}
override fun isFinallyMarkerRequired(): Boolean = isFinallyMarkerRequired(codegen.getContext())
override val isFinallyMarkerRequired: Boolean
get() = isFinallyMarkerRequired(codegen.getContext())
override val compilationContextDescriptor override val compilationContextDescriptor
get() = codegen.getContext().contextDescriptor get() = codegen.getContext().contextDescriptor
@@ -301,16 +299,6 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
return labels.associateWith { null } // TODO add break/continue labels return labels.associateWith { null } // TODO add break/continue labels
} }
fun initializeInlineFunctionContext(functionDescriptor: FunctionDescriptor) {
context = getContext(
functionDescriptor,
functionDescriptor,
state,
DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)?.containingFile as? KtFile,
additionalInnerClasses
)
}
override fun reportSuspensionPointInsideMonitor(stackTraceElement: String) { override fun reportSuspensionPointInsideMonitor(stackTraceElement: String) {
org.jetbrains.kotlin.codegen.coroutines.reportSuspensionPointInsideMonitor(callElement, state, stackTraceElement) org.jetbrains.kotlin.codegen.coroutines.reportSuspensionPointInsideMonitor(callElement, state, stackTraceElement)
} }
@@ -37,12 +37,7 @@ interface SourceCompilerForInline {
fun generateLambdaBody(lambdaInfo: ExpressionLambda, reifiedTypeParameters: ReifiedTypeParametersUsages): SMAPAndMethodNode fun generateLambdaBody(lambdaInfo: ExpressionLambda, reifiedTypeParameters: ReifiedTypeParametersUsages): SMAPAndMethodNode
fun doCreateMethodNodeFromSource( fun compileInlineFunction(jvmSignature: JvmMethodSignature, callDefault: Boolean, asmMethod: Method): SMAPAndMethodNode
callableDescriptor: FunctionDescriptor,
jvmSignature: JvmMethodSignature,
callDefault: Boolean,
asmMethod: Method
): SMAPAndMethodNode
fun hasFinallyBlocks(): Boolean fun hasFinallyBlocks(): Boolean
@@ -53,9 +48,9 @@ interface SourceCompilerForInline {
fun generateFinallyBlocksIfNeeded(codegen: BaseExpressionCodegen, returnType: Type, afterReturnLabel: Label, target: Label?) fun generateFinallyBlocksIfNeeded(codegen: BaseExpressionCodegen, returnType: Type, afterReturnLabel: Label, target: Label?)
fun isCallInsideSameModuleAsDeclared(functionDescriptor: FunctionDescriptor): Boolean val isCallInsideSameModuleAsCallee: Boolean
fun isFinallyMarkerRequired(): Boolean val isFinallyMarkerRequired: Boolean
val compilationContextDescriptor: DeclarationDescriptor val compilationContextDescriptor: DeclarationDescriptor
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.isReleaseCoroutines import org.jetbrains.kotlin.config.isReleaseCoroutines
import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
@@ -1241,11 +1240,11 @@ class ExpressionCodegen(
val gapStart = markNewLinkedLabel() val gapStart = markNewLinkedLabel()
data.localGapScope(tryWithFinallyInfo) { data.localGapScope(tryWithFinallyInfo) {
finallyDepth++ finallyDepth++
if (isFinallyMarkerRequired()) { if (isFinallyMarkerRequired) {
generateFinallyMarker(mv, finallyDepth, true) generateFinallyMarker(mv, finallyDepth, true)
} }
tryWithFinallyInfo.onExit.accept(this, data).discard() tryWithFinallyInfo.onExit.accept(this, data).discard()
if (isFinallyMarkerRequired()) { if (isFinallyMarkerRequired) {
generateFinallyMarker(mv, finallyDepth, false) generateFinallyMarker(mv, finallyDepth, false)
} }
finallyDepth-- finallyDepth--
@@ -1445,9 +1444,8 @@ class ExpressionCodegen(
} }
} }
fun isFinallyMarkerRequired(): Boolean { val isFinallyMarkerRequired: Boolean
return irFunction.isInline || inlinedInto != null get() = irFunction.isInline || inlinedInto != null
}
val IrType.isReifiedTypeParameter: Boolean val IrType.isReifiedTypeParameter: Boolean
get() = this.classifierOrNull?.safeAs<IrTypeParameterSymbol>()?.owner?.isReified == true get() = this.classifierOrNull?.safeAs<IrTypeParameterSymbol>()?.owner?.isReified == true
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.Position import org.jetbrains.kotlin.incremental.components.Position
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBasedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrLoop import org.jetbrains.kotlin.ir.expressions.IrLoop
@@ -105,12 +104,7 @@ class IrSourceCompilerForInline(
return FunctionCodegen(lambdaInfo.function, codegen.classCodegen).generate(codegen, reifiedTypeParameters) return FunctionCodegen(lambdaInfo.function, codegen.classCodegen).generate(codegen, reifiedTypeParameters)
} }
override fun doCreateMethodNodeFromSource( override fun compileInlineFunction(jvmSignature: JvmMethodSignature, callDefault: Boolean, asmMethod: Method): SMAPAndMethodNode =
callableDescriptor: FunctionDescriptor,
jvmSignature: JvmMethodSignature,
callDefault: Boolean,
asmMethod: Method
): SMAPAndMethodNode =
ClassCodegen.getOrCreate(callee.parentAsClass, codegen.context).generateMethodNode(callee) ClassCodegen.getOrCreate(callee.parentAsClass, codegen.context).generateMethodNode(callee)
override fun hasFinallyBlocks() = data.hasFinallyBlocks() override fun hasFinallyBlocks() = data.hasFinallyBlocks()
@@ -129,17 +123,11 @@ class IrSourceCompilerForInline(
} }
@OptIn(ObsoleteDescriptorBasedAPI::class) @OptIn(ObsoleteDescriptorBasedAPI::class)
override fun isCallInsideSameModuleAsDeclared(functionDescriptor: FunctionDescriptor): Boolean { override val isCallInsideSameModuleAsCallee: Boolean
require(functionDescriptor is IrBasedSimpleFunctionDescriptor) { get() = callee.module == codegen.irFunction.module
"expected an IrBasedSimpleFunctionDescriptor, got $functionDescriptor"
}
val function = functionDescriptor.owner
return function.module == codegen.irFunction.module
}
override fun isFinallyMarkerRequired(): Boolean { override val isFinallyMarkerRequired: Boolean
return codegen.isFinallyMarkerRequired() get() = codegen.isFinallyMarkerRequired
}
override val compilationContextDescriptor: DeclarationDescriptor override val compilationContextDescriptor: DeclarationDescriptor
get() = compilationContextFunctionDescriptor get() = compilationContextFunctionDescriptor