JVM: remove functionDescriptor from InlineCodegen
This commit is contained in:
@@ -10,15 +10,11 @@ import org.jetbrains.kotlin.codegen.*
|
|||||||
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
|
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
|
||||||
import org.jetbrains.kotlin.codegen.context.ClosureContext
|
import org.jetbrains.kotlin.codegen.context.ClosureContext
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.incremental.components.Position
|
|
||||||
import org.jetbrains.kotlin.incremental.components.ScopeKind
|
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||||
import org.jetbrains.kotlin.resolve.inline.isInlineOnly
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
@@ -29,18 +25,11 @@ import kotlin.math.max
|
|||||||
abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||||
protected val codegen: T,
|
protected val codegen: T,
|
||||||
protected val state: GenerationState,
|
protected val state: GenerationState,
|
||||||
protected val functionDescriptor: FunctionDescriptor,
|
|
||||||
protected val jvmSignature: JvmMethodSignature,
|
protected val jvmSignature: JvmMethodSignature,
|
||||||
private val typeParameterMappings: TypeParameterMappings<*>,
|
private val typeParameterMappings: TypeParameterMappings<*>,
|
||||||
protected val sourceCompiler: SourceCompilerForInline,
|
protected val sourceCompiler: SourceCompilerForInline,
|
||||||
protected val reifiedTypeInliner: ReifiedTypeInliner<*>
|
protected val reifiedTypeInliner: ReifiedTypeInliner<*>
|
||||||
) {
|
) {
|
||||||
init {
|
|
||||||
assert(InlineUtil.isInline(functionDescriptor)) {
|
|
||||||
"InlineCodegen can inline only inline functions: $functionDescriptor"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: implement AS_FUNCTION inline strategy
|
// TODO: implement AS_FUNCTION inline strategy
|
||||||
private val asFunctionInline = false
|
private val asFunctionInline = false
|
||||||
|
|
||||||
@@ -52,15 +41,6 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
protected var maskStartIndex = -1
|
protected var maskStartIndex = -1
|
||||||
protected var methodHandleInDefaultMethodIndex = -1
|
protected var methodHandleInDefaultMethodIndex = -1
|
||||||
|
|
||||||
init {
|
|
||||||
if (functionDescriptor !is FictitiousArrayConstructor) {
|
|
||||||
//track changes for property accessor and @JvmName inline functions/property accessors
|
|
||||||
if (jvmSignature.asmMethod.name != functionDescriptor.name.asString()) {
|
|
||||||
trackLookup(functionDescriptor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun throwCompilationException(
|
protected fun throwCompilationException(
|
||||||
nodeAndSmap: SMAPAndMethodNode?, e: Exception, generateNodeText: Boolean
|
nodeAndSmap: SMAPAndMethodNode?, e: Exception, generateNodeText: Boolean
|
||||||
): CompilationException {
|
): CompilationException {
|
||||||
@@ -68,7 +48,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
val element = DescriptorToSourceUtils.descriptorToDeclaration(contextDescriptor)
|
val element = DescriptorToSourceUtils.descriptorToDeclaration(contextDescriptor)
|
||||||
val node = nodeAndSmap?.node
|
val node = nodeAndSmap?.node
|
||||||
throw CompilationException(
|
throw CompilationException(
|
||||||
"Couldn't inline method call '" + functionDescriptor.name + "' into\n" +
|
"Couldn't inline method call '${jvmSignature.asmMethod}' into\n" +
|
||||||
DescriptorRenderer.DEBUG_TEXT.render(contextDescriptor) + "\n" +
|
DescriptorRenderer.DEBUG_TEXT.render(contextDescriptor) + "\n" +
|
||||||
(element?.text ?: "<no source>") +
|
(element?.text ?: "<no source>") +
|
||||||
if (generateNodeText) "\nCause: " + node.nodeText else "",
|
if (generateNodeText) "\nCause: " + node.nodeText else "",
|
||||||
@@ -81,13 +61,13 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
AsmUtil.genThrow(codegen.visitor, "java/lang/UnsupportedOperationException", "Call is part of inline cycle: $text")
|
AsmUtil.genThrow(codegen.visitor, "java/lang/UnsupportedOperationException", "Call is part of inline cycle: $text")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun performInline(inlineDefaultLambdas: Boolean, registerLineNumberAfterwards: Boolean) {
|
fun performInline(registerLineNumberAfterwards: Boolean, isInlineOnly: Boolean, isSuspend: Boolean) {
|
||||||
var nodeAndSmap: SMAPAndMethodNode? = null
|
var nodeAndSmap: SMAPAndMethodNode? = null
|
||||||
try {
|
try {
|
||||||
nodeAndSmap = sourceCompiler.compileInlineFunction(jvmSignature).apply {
|
nodeAndSmap = sourceCompiler.compileInlineFunction(jvmSignature).apply {
|
||||||
node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
|
node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
|
||||||
}
|
}
|
||||||
val result = inlineCall(nodeAndSmap, inlineDefaultLambdas)
|
val result = inlineCall(nodeAndSmap, isInlineOnly, isSuspend)
|
||||||
leaveTemps()
|
leaveTemps()
|
||||||
codegen.propagateChildReifiedTypeParametersUsages(result.reifiedTypeParametersUsages)
|
codegen.propagateChildReifiedTypeParametersUsages(result.reifiedTypeParametersUsages)
|
||||||
codegen.markLineNumberAfterInlineIfNeeded(registerLineNumberAfterwards)
|
codegen.markLineNumberAfterInlineIfNeeded(registerLineNumberAfterwards)
|
||||||
@@ -109,8 +89,6 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
//
|
//
|
||||||
// Instead of checking for loops precisely, we just check if there are any backward jumps -
|
// Instead of checking for loops precisely, we just check if there are any backward jumps -
|
||||||
// that is, a jump from instruction #i to instruction #j where j < i
|
// that is, a jump from instruction #i to instruction #j where j < i
|
||||||
|
|
||||||
if (functionDescriptor.isSuspend) return false
|
|
||||||
if (methodNode.tryCatchBlocks.isNotEmpty()) return false
|
if (methodNode.tryCatchBlocks.isNotEmpty()) return false
|
||||||
|
|
||||||
fun isBackwardJump(fromIndex: Int, toLabel: LabelNode) =
|
fun isBackwardJump(fromIndex: Int, toLabel: LabelNode) =
|
||||||
@@ -162,9 +140,9 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
expressionMap[closureInfo.index] = lambdaInfo
|
expressionMap[closureInfo.index] = lambdaInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun inlineCall(nodeAndSmap: SMAPAndMethodNode, inlineDefaultLambda: Boolean): InlineResult {
|
private fun inlineCall(nodeAndSmap: SMAPAndMethodNode, isInlineOnly: Boolean, isSuspend: Boolean): InlineResult {
|
||||||
val node = nodeAndSmap.node
|
val node = nodeAndSmap.node
|
||||||
if (inlineDefaultLambda) {
|
if (maskStartIndex != -1) {
|
||||||
for (lambda in extractDefaultLambdas(node)) {
|
for (lambda in extractDefaultLambdas(node)) {
|
||||||
invocationParamBuilder.buildParameters().getParameterByDeclarationSlot(lambda.offset).functionalArgument = lambda
|
invocationParamBuilder.buildParameters().getParameterByDeclarationSlot(lambda.offset).functionalArgument = lambda
|
||||||
val prev = expressionMap.put(lambda.offset, lambda)
|
val prev = expressionMap.put(lambda.offset, lambda)
|
||||||
@@ -190,7 +168,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
node, parameters, info, FieldRemapper(null, null, parameters), sourceCompiler.isCallInsideSameModuleAsCallee,
|
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 (isInlineOnly) InlineOnlySmapSkipper(codegen) else null,
|
||||||
!isInlinedToInlineFunInKotlinRuntime()
|
!isInlinedToInlineFunInKotlinRuntime()
|
||||||
) //with captured
|
) //with captured
|
||||||
|
|
||||||
@@ -215,7 +193,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
// needs to be inserted before the code that actually uses it.
|
// needs to be inserted before the code that actually uses it.
|
||||||
generateAssertFieldIfNeeded(info)
|
generateAssertFieldIfNeeded(info)
|
||||||
|
|
||||||
val shouldSpillStack = !canSkipStackSpillingOnInline(node)
|
val shouldSpillStack = isSuspend || !canSkipStackSpillingOnInline(node)
|
||||||
if (shouldSpillStack) {
|
if (shouldSpillStack) {
|
||||||
addInlineMarker(codegen.visitor, true)
|
addInlineMarker(codegen.visitor, true)
|
||||||
}
|
}
|
||||||
@@ -389,21 +367,6 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun trackLookup(functionOrAccessor: FunctionDescriptor) {
|
|
||||||
val functionOrAccessorName = jvmSignature.asmMethod.name
|
|
||||||
val lookupTracker = state.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: return
|
|
||||||
val location = sourceCompiler.lookupLocation.location ?: return
|
|
||||||
val position = if (lookupTracker.requiresPosition) location.position else Position.NO_POSITION
|
|
||||||
val classOrPackageFragment = functionOrAccessor.containingDeclaration
|
|
||||||
lookupTracker.record(
|
|
||||||
location.filePath,
|
|
||||||
position,
|
|
||||||
DescriptorUtils.getFqName(classOrPackageFragment).asString(),
|
|
||||||
ScopeKind.CLASSIFIER,
|
|
||||||
functionOrAccessorName
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun StackValue.isCapturedInlineParameter(): Boolean {
|
private fun StackValue.isCapturedInlineParameter(): Boolean {
|
||||||
val field = if (this is StackValue.FieldForSharedVar) receiver else this
|
val field = if (this is StackValue.FieldForSharedVar) receiver else this
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
|
|||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil.isInlinableParameterExpression
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil.isInlinableParameterExpression
|
||||||
|
import org.jetbrains.kotlin.resolve.inline.isInlineOnly
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -39,14 +40,14 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
|||||||
class PsiInlineCodegen(
|
class PsiInlineCodegen(
|
||||||
codegen: ExpressionCodegen,
|
codegen: ExpressionCodegen,
|
||||||
state: GenerationState,
|
state: GenerationState,
|
||||||
function: FunctionDescriptor,
|
private val functionDescriptor: FunctionDescriptor,
|
||||||
signature: JvmMethodSignature,
|
signature: JvmMethodSignature,
|
||||||
typeParameterMappings: TypeParameterMappings<KotlinType>,
|
typeParameterMappings: TypeParameterMappings<KotlinType>,
|
||||||
sourceCompiler: SourceCompilerForInline,
|
sourceCompiler: SourceCompilerForInline,
|
||||||
private val methodOwner: Type,
|
private val methodOwner: Type,
|
||||||
private val actualDispatchReceiver: Type
|
private val actualDispatchReceiver: Type
|
||||||
) : InlineCodegen<ExpressionCodegen>(
|
) : InlineCodegen<ExpressionCodegen>(
|
||||||
codegen, state, function, signature, typeParameterMappings, sourceCompiler,
|
codegen, state, signature, typeParameterMappings, sourceCompiler,
|
||||||
ReifiedTypeInliner(
|
ReifiedTypeInliner(
|
||||||
typeParameterMappings, PsiInlineIntrinsicsSupport(state), codegen.typeSystem,
|
typeParameterMappings, PsiInlineIntrinsicsSupport(state), codegen.typeSystem,
|
||||||
state.languageVersionSettings, state.unifiedNullChecks
|
state.languageVersionSettings, state.unifiedNullChecks
|
||||||
@@ -83,7 +84,7 @@ class PsiInlineCodegen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
performInline(callDefault, registerLineNumber)
|
performInline(registerLineNumber, functionDescriptor.isInlineOnly(), functionDescriptor.isSuspend)
|
||||||
} finally {
|
} finally {
|
||||||
state.globalInlineContext.exitFromInlining()
|
state.globalInlineContext.exitFromInlining()
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-14
@@ -52,7 +52,7 @@ class PsiSourceCompilerForInline(
|
|||||||
codegen.state,
|
codegen.state,
|
||||||
DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)?.containingFile as? KtFile,
|
DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)?.containingFile as? KtFile,
|
||||||
additionalInnerClasses
|
additionalInnerClasses
|
||||||
)
|
) as MethodContext
|
||||||
|
|
||||||
override val lookupLocation = KotlinLookupLocation(callElement)
|
override val lookupLocation = KotlinLookupLocation(callElement)
|
||||||
|
|
||||||
@@ -246,6 +246,9 @@ class PsiSourceCompilerForInline(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val asmMethod = if (callDefault) mapDefault() else jvmSignature.asmMethod
|
val asmMethod = if (callDefault) mapDefault() else jvmSignature.asmMethod
|
||||||
|
if (asmMethod.name != functionDescriptor.name.asString()) {
|
||||||
|
trackLookup(DescriptorUtils.getFqNameSafe(functionDescriptor.containingDeclaration), asmMethod.name) // ?
|
||||||
|
}
|
||||||
|
|
||||||
val directMember = getDirectMemberAndCallableFromObject()
|
val directMember = getDirectMemberAndCallableFromObject()
|
||||||
if (directMember is DescriptorWithContainerSource) {
|
if (directMember is DescriptorWithContainerSource) {
|
||||||
@@ -254,12 +257,8 @@ class PsiSourceCompilerForInline(
|
|||||||
return loadCompiledInlineFunction(containerId, asmMethod, functionDescriptor.isSuspend, isMangled, state)
|
return loadCompiledInlineFunction(containerId, asmMethod, functionDescriptor.isSuspend, isMangled, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
val element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)
|
val element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor) as? KtDeclarationWithBody
|
||||||
|
?: throw IllegalStateException("Couldn't find declaration for function $functionDescriptor")
|
||||||
if (!(element is KtNamedFunction || element is KtPropertyAccessor)) {
|
|
||||||
throw IllegalStateException("Couldn't find declaration for function $functionDescriptor")
|
|
||||||
}
|
|
||||||
val inliningFunction = element as KtDeclarationWithBody?
|
|
||||||
|
|
||||||
val node = MethodNode(
|
val node = MethodNode(
|
||||||
Opcodes.API_VERSION,
|
Opcodes.API_VERSION,
|
||||||
@@ -271,13 +270,10 @@ class PsiSourceCompilerForInline(
|
|||||||
|
|
||||||
//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 methodContext = parentContext.intoFunction(functionDescriptor)
|
|
||||||
|
|
||||||
val smap = if (callDefault) {
|
val smap = if (callDefault) {
|
||||||
val implementationOwner = state.typeMapper.mapImplementationOwner(functionDescriptor)
|
val implementationOwner = state.typeMapper.mapImplementationOwner(functionDescriptor)
|
||||||
val parentCodegen = FakeMemberCodegen(
|
val parentCodegen = FakeMemberCodegen(
|
||||||
codegen.parentCodegen, inliningFunction!!, methodContext.parentContext as FieldOwnerContext<*>,
|
codegen.parentCodegen, element, context.parentContext as FieldOwnerContext<*>,
|
||||||
implementationOwner.internalName,
|
implementationOwner.internalName,
|
||||||
additionalInnerClasses,
|
additionalInnerClasses,
|
||||||
false
|
false
|
||||||
@@ -286,12 +282,12 @@ class PsiSourceCompilerForInline(
|
|||||||
throw IllegalStateException("Property accessors with default parameters not supported $functionDescriptor")
|
throw IllegalStateException("Property accessors with default parameters not supported $functionDescriptor")
|
||||||
}
|
}
|
||||||
FunctionCodegen.generateDefaultImplBody(
|
FunctionCodegen.generateDefaultImplBody(
|
||||||
methodContext, functionDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
|
context, functionDescriptor, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
|
||||||
inliningFunction as KtNamedFunction?, parentCodegen, asmMethod
|
element as KtNamedFunction?, parentCodegen, asmMethod
|
||||||
)
|
)
|
||||||
SMAP(parentCodegen.orCreateSourceMapper.resultMappings)
|
SMAP(parentCodegen.orCreateSourceMapper.resultMappings)
|
||||||
} else {
|
} else {
|
||||||
generateMethodBody(maxCalcAdapter, functionDescriptor, methodContext, inliningFunction!!, jvmSignature, null)
|
generateMethodBody(maxCalcAdapter, functionDescriptor, context, element, jvmSignature, null)
|
||||||
}
|
}
|
||||||
maxCalcAdapter.visitMaxs(-1, -1)
|
maxCalcAdapter.visitMaxs(-1, -1)
|
||||||
maxCalcAdapter.visitEnd()
|
maxCalcAdapter.visitEnd()
|
||||||
|
|||||||
@@ -11,10 +11,14 @@ import org.jetbrains.kotlin.codegen.BaseExpressionCodegen
|
|||||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||||
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.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
|
import org.jetbrains.kotlin.incremental.components.Position
|
||||||
|
import org.jetbrains.kotlin.incremental.components.ScopeKind
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
@@ -64,6 +68,19 @@ interface SourceCompilerForInline {
|
|||||||
fun reportSuspensionPointInsideMonitor(stackTraceElement: String)
|
fun reportSuspensionPointInsideMonitor(stackTraceElement: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun SourceCompilerForInline.trackLookup(container: FqName, functionName: String) {
|
||||||
|
val lookupTracker = state.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: return
|
||||||
|
val location = lookupLocation.location ?: return
|
||||||
|
val position = if (lookupTracker.requiresPosition) location.position else Position.NO_POSITION
|
||||||
|
lookupTracker.record(
|
||||||
|
location.filePath,
|
||||||
|
position,
|
||||||
|
container.asString(),
|
||||||
|
ScopeKind.CLASSIFIER,
|
||||||
|
functionName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun loadCompiledInlineFunction(
|
fun loadCompiledInlineFunction(
|
||||||
containerId: ClassId,
|
containerId: ClassId,
|
||||||
asmMethod: Method,
|
asmMethod: Method,
|
||||||
|
|||||||
+2
-6
@@ -41,9 +41,7 @@ class IrInlineCodegen(
|
|||||||
sourceCompiler: SourceCompilerForInline,
|
sourceCompiler: SourceCompilerForInline,
|
||||||
reifiedTypeInliner: ReifiedTypeInliner<IrType>
|
reifiedTypeInliner: ReifiedTypeInliner<IrType>
|
||||||
) :
|
) :
|
||||||
InlineCodegen<ExpressionCodegen>(
|
InlineCodegen<ExpressionCodegen>(codegen, state, signature, typeParameterMappings, sourceCompiler, reifiedTypeInliner),
|
||||||
codegen, state, function.toIrBasedDescriptor(), signature, typeParameterMappings, sourceCompiler, reifiedTypeInliner
|
|
||||||
),
|
|
||||||
IrInlineCallGenerator {
|
IrInlineCallGenerator {
|
||||||
|
|
||||||
override fun generateAssertFieldIfNeeded(info: RootInliningContext) {
|
override fun generateAssertFieldIfNeeded(info: RootInliningContext) {
|
||||||
@@ -126,8 +124,7 @@ class IrInlineCodegen(
|
|||||||
expression: IrFunctionAccessExpression,
|
expression: IrFunctionAccessExpression,
|
||||||
isInsideIfCondition: Boolean,
|
isInsideIfCondition: Boolean,
|
||||||
) {
|
) {
|
||||||
// Always look for default lambdas to allow custom default argument handling in compiler plugins.
|
performInline(isInsideIfCondition, function.isInlineOnly(), function.isSuspend)
|
||||||
performInline(inlineDefaultLambdas = true, registerLineNumberAfterwards = isInsideIfCondition)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun genCycleStub(text: String, codegen: ExpressionCodegen) {
|
override fun genCycleStub(text: String, codegen: ExpressionCodegen) {
|
||||||
@@ -135,7 +132,6 @@ class IrInlineCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun extractDefaultLambdas(node: MethodNode): List<DefaultLambda> {
|
override fun extractDefaultLambdas(node: MethodNode): List<DefaultLambda> {
|
||||||
if (maskStartIndex == -1) return listOf()
|
|
||||||
return expandMaskConditionsAndUpdateVariableNodes(
|
return expandMaskConditionsAndUpdateVariableNodes(
|
||||||
node, maskStartIndex, maskValues, methodHandleInDefaultMethodIndex,
|
node, maskStartIndex, maskValues, methodHandleInDefaultMethodIndex,
|
||||||
extractDefaultLambdaOffsetAndDescriptor(jvmSignature, function),
|
extractDefaultLambdaOffsetAndDescriptor(jvmSignature, function),
|
||||||
|
|||||||
+4
@@ -27,6 +27,7 @@ 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
|
||||||
import org.jetbrains.kotlin.ir.util.isSuspend
|
import org.jetbrains.kotlin.ir.util.isSuspend
|
||||||
|
import org.jetbrains.kotlin.ir.util.kotlinFqName
|
||||||
import org.jetbrains.kotlin.ir.util.module
|
import org.jetbrains.kotlin.ir.util.module
|
||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
@@ -108,6 +109,9 @@ class IrSourceCompilerForInline(
|
|||||||
generateInlineIntrinsicForIr(state.languageVersionSettings, callee.toIrBasedDescriptor())?.let {
|
generateInlineIntrinsicForIr(state.languageVersionSettings, callee.toIrBasedDescriptor())?.let {
|
||||||
return it
|
return it
|
||||||
}
|
}
|
||||||
|
if (jvmSignature.asmMethod.name != callee.name.asString()) {
|
||||||
|
trackLookup(callee.parentAsClass.kotlinFqName, jvmSignature.asmMethod.name) // ?
|
||||||
|
}
|
||||||
callee.parentClassId?.let {
|
callee.parentClassId?.let {
|
||||||
return loadCompiledInlineFunction(it, jvmSignature.asmMethod, callee.isSuspend, callee.hasMangledReturnType, state)
|
return loadCompiledInlineFunction(it, jvmSignature.asmMethod, callee.isSuspend, callee.hasMangledReturnType, state)
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-16
@@ -179,7 +179,7 @@ private fun IrDeclarationWithVisibility.specialCaseVisibility(kind: OwnerKind?):
|
|||||||
return Opcodes.ACC_PRIVATE
|
return Opcodes.ACC_PRIVATE
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInlineOnlyPrivateInBytecode() || isInlineOnlyPropertyAccessor()) {
|
if (isInlineOnlyPrivateInBytecode()) {
|
||||||
return Opcodes.ACC_PRIVATE
|
return Opcodes.ACC_PRIVATE
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,26 +223,18 @@ private tailrec fun isInlineOrContainedInInline(declaration: IrDeclaration?): Bo
|
|||||||
|
|
||||||
/* Borrowed from inlineOnly.kt */
|
/* Borrowed from inlineOnly.kt */
|
||||||
|
|
||||||
fun IrDeclarationWithVisibility.isInlineOnlyOrReifiable(): Boolean =
|
|
||||||
this is IrFunction && (isReifiable() || isInlineOnly())
|
|
||||||
|
|
||||||
fun IrDeclarationWithVisibility.isEffectivelyInlineOnly(): Boolean =
|
fun IrDeclarationWithVisibility.isEffectivelyInlineOnly(): Boolean =
|
||||||
isInlineOnlyOrReifiable() || isInlineOnlyPrivateInBytecode() || isInlineOnlyPropertyAccessor()
|
this is IrFunction && (isReifiable() || isInlineOnly() || isPrivateInlineSuspend())
|
||||||
|
|
||||||
fun IrDeclarationWithVisibility.isInlineOnlyPrivateInBytecode(): Boolean =
|
private fun IrDeclarationWithVisibility.isInlineOnlyPrivateInBytecode(): Boolean =
|
||||||
(this is IrFunction && isInlineOnly()) || isPrivateInlineSuspend()
|
this is IrFunction && (isInlineOnly() || isPrivateInlineSuspend())
|
||||||
|
|
||||||
private fun IrDeclarationWithVisibility.isPrivateInlineSuspend(): Boolean =
|
private fun IrFunction.isPrivateInlineSuspend(): Boolean =
|
||||||
this is IrFunction && isSuspend && isInline && visibility == DescriptorVisibilities.PRIVATE
|
isSuspend && isInline && visibility == DescriptorVisibilities.PRIVATE
|
||||||
|
|
||||||
private fun IrDeclarationWithVisibility.isInlineOnlyPropertyAccessor(): Boolean {
|
|
||||||
if (this !is IrSimpleFunction) return false
|
|
||||||
val propertySymbol = correspondingPropertySymbol ?: return false
|
|
||||||
return propertySymbol.owner.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrFunction.isInlineOnly() =
|
fun IrFunction.isInlineOnly() =
|
||||||
isInline && hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME)
|
(isInline && hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME)) ||
|
||||||
|
(this is IrSimpleFunction && correspondingPropertySymbol?.owner?.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME) == true)
|
||||||
|
|
||||||
fun IrFunction.isReifiable() = typeParameters.any { it.isReified }
|
fun IrFunction.isReifiable() = typeParameters.any { it.isReified }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user