JVM: move loadCompiledInlineFunction out of InlineCodegen
This commit is contained in:
+2
-2
@@ -6,7 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.codegen
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegen
|
import org.jetbrains.kotlin.codegen.inline.loadCompiledInlineFunction
|
||||||
import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckParameterIsNotNull
|
import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckParameterIsNotNull
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
@@ -74,7 +74,7 @@ class DelegatedPropertiesCodegenHelper(private val state: GenerationState) {
|
|||||||
val containerId = KotlinTypeMapper.getContainingClassesForDeserializedCallable(calleeDescriptor).implClassId
|
val containerId = KotlinTypeMapper.getContainingClassesForDeserializedCallable(calleeDescriptor).implClassId
|
||||||
val asmMethod = state.typeMapper.mapAsmMethod(calleeDescriptor)
|
val asmMethod = state.typeMapper.mapAsmMethod(calleeDescriptor)
|
||||||
val isMangled = requiresFunctionNameManglingForReturnType(calleeDescriptor)
|
val isMangled = requiresFunctionNameManglingForReturnType(calleeDescriptor)
|
||||||
val methodNode = InlineCodegen.loadCompiledInlineFunction(containerId, asmMethod, calleeDescriptor.isSuspend, isMangled, state).node
|
val methodNode = loadCompiledInlineFunction(containerId, asmMethod, calleeDescriptor.isSuspend, isMangled, state).node
|
||||||
return isMetadataParameterUsedInCompiledMethodBody(metadataParameterIndex, methodNode)
|
return isMetadataParameterUsedInCompiledMethodBody(metadataParameterIndex, methodNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,11 @@ import com.intellij.psi.PsiElement
|
|||||||
import org.jetbrains.kotlin.codegen.*
|
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.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.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.Position
|
||||||
import org.jetbrains.kotlin.incremental.components.ScopeKind
|
import org.jetbrains.kotlin.incremental.components.ScopeKind
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
|
||||||
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
|
||||||
@@ -27,7 +25,6 @@ import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
|||||||
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
|
||||||
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.tree.*
|
import org.jetbrains.org.objectweb.asm.tree.*
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
@@ -424,50 +421,6 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun loadCompiledInlineFunction(
|
|
||||||
containerId: ClassId,
|
|
||||||
asmMethod: Method,
|
|
||||||
isSuspend: Boolean,
|
|
||||||
isMangled: Boolean,
|
|
||||||
state: GenerationState
|
|
||||||
): SMAPAndMethodNode {
|
|
||||||
val containerType = AsmUtil.asmTypeByClassId(containerId)
|
|
||||||
val bytes = state.inlineCache.classBytes.getOrPut(containerId) {
|
|
||||||
findVirtualFile(state, containerId)?.contentsToByteArray()
|
|
||||||
?: throw IllegalStateException("Couldn't find declaration file for $containerId")
|
|
||||||
}
|
|
||||||
val resultInCache = state.inlineCache.methodNodeById.getOrPut(MethodId(containerType.descriptor, asmMethod)) {
|
|
||||||
getMethodNode(containerType, bytes, asmMethod.name, asmMethod.descriptor, isSuspend, isMangled)
|
|
||||||
}
|
|
||||||
return SMAPAndMethodNode(cloneMethodNode(resultInCache.node), resultInCache.classSMAP)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getMethodNode(
|
|
||||||
owner: Type,
|
|
||||||
bytes: ByteArray,
|
|
||||||
name: String,
|
|
||||||
descriptor: String,
|
|
||||||
isSuspend: Boolean,
|
|
||||||
isMangled: Boolean
|
|
||||||
): SMAPAndMethodNode {
|
|
||||||
getMethodNode(owner, bytes, name, descriptor, isSuspend)?.let { return it }
|
|
||||||
if (isMangled) {
|
|
||||||
// Compatibility with old inline class ABI versions.
|
|
||||||
val dashIndex = name.indexOf('-')
|
|
||||||
val nameWithoutManglingSuffix = if (dashIndex > 0) name.substring(0, dashIndex) else name
|
|
||||||
if (nameWithoutManglingSuffix != name) {
|
|
||||||
getMethodNode(owner, bytes, nameWithoutManglingSuffix, descriptor, isSuspend)?.let { return it }
|
|
||||||
}
|
|
||||||
getMethodNode(owner, bytes, "$nameWithoutManglingSuffix-impl", descriptor, isSuspend)?.let { return it }
|
|
||||||
}
|
|
||||||
throw IllegalStateException("couldn't find inline method $owner.$name$descriptor")
|
|
||||||
}
|
|
||||||
|
|
||||||
// If an `inline suspend fun` has a state machine, it should have a `$$forInline` version without one.
|
|
||||||
private fun getMethodNode(owner: Type, bytes: ByteArray, name: String, descriptor: String, isSuspend: Boolean) =
|
|
||||||
(if (isSuspend) getMethodNode(bytes, name + FOR_INLINE_SUFFIX, descriptor, owner) else null)
|
|
||||||
?: getMethodNode(bytes, name, descriptor, owner)
|
|
||||||
|
|
||||||
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
|
||||||
return field is StackValue.Field && field.descriptor is ParameterDescriptor &&
|
return field is StackValue.Field && field.descriptor is ParameterDescriptor &&
|
||||||
|
|||||||
+1
-1
@@ -247,7 +247,7 @@ class PsiSourceCompilerForInline(
|
|||||||
if (directMember is DescriptorWithContainerSource) {
|
if (directMember is DescriptorWithContainerSource) {
|
||||||
val containerId = KotlinTypeMapper.getContainingClassesForDeserializedCallable(directMember).implClassId
|
val containerId = KotlinTypeMapper.getContainingClassesForDeserializedCallable(directMember).implClassId
|
||||||
val isMangled = requiresFunctionNameManglingForReturnType(functionDescriptor)
|
val isMangled = requiresFunctionNameManglingForReturnType(functionDescriptor)
|
||||||
return InlineCodegen.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)
|
||||||
|
|||||||
@@ -6,8 +6,10 @@
|
|||||||
package org.jetbrains.kotlin.codegen.inline
|
package org.jetbrains.kotlin.codegen.inline
|
||||||
|
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.codegen.BaseExpressionCodegen
|
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.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
@@ -61,3 +63,47 @@ interface SourceCompilerForInline {
|
|||||||
|
|
||||||
fun reportSuspensionPointInsideMonitor(stackTraceElement: String)
|
fun reportSuspensionPointInsideMonitor(stackTraceElement: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun loadCompiledInlineFunction(
|
||||||
|
containerId: ClassId,
|
||||||
|
asmMethod: Method,
|
||||||
|
isSuspend: Boolean,
|
||||||
|
isMangled: Boolean,
|
||||||
|
state: GenerationState
|
||||||
|
): SMAPAndMethodNode {
|
||||||
|
val containerType = AsmUtil.asmTypeByClassId(containerId)
|
||||||
|
val bytes = state.inlineCache.classBytes.getOrPut(containerId) {
|
||||||
|
findVirtualFile(state, containerId)?.contentsToByteArray()
|
||||||
|
?: throw IllegalStateException("Couldn't find declaration file for $containerId")
|
||||||
|
}
|
||||||
|
val resultInCache = state.inlineCache.methodNodeById.getOrPut(MethodId(containerType.descriptor, asmMethod)) {
|
||||||
|
getMethodNode(containerType, bytes, asmMethod.name, asmMethod.descriptor, isSuspend, isMangled)
|
||||||
|
}
|
||||||
|
return SMAPAndMethodNode(cloneMethodNode(resultInCache.node), resultInCache.classSMAP)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getMethodNode(
|
||||||
|
owner: Type,
|
||||||
|
bytes: ByteArray,
|
||||||
|
name: String,
|
||||||
|
descriptor: String,
|
||||||
|
isSuspend: Boolean,
|
||||||
|
isMangled: Boolean
|
||||||
|
): SMAPAndMethodNode {
|
||||||
|
getMethodNode(owner, bytes, name, descriptor, isSuspend)?.let { return it }
|
||||||
|
if (isMangled) {
|
||||||
|
// Compatibility with old inline class ABI versions.
|
||||||
|
val dashIndex = name.indexOf('-')
|
||||||
|
val nameWithoutManglingSuffix = if (dashIndex > 0) name.substring(0, dashIndex) else name
|
||||||
|
if (nameWithoutManglingSuffix != name) {
|
||||||
|
getMethodNode(owner, bytes, nameWithoutManglingSuffix, descriptor, isSuspend)?.let { return it }
|
||||||
|
}
|
||||||
|
getMethodNode(owner, bytes, "$nameWithoutManglingSuffix-impl", descriptor, isSuspend)?.let { return it }
|
||||||
|
}
|
||||||
|
throw IllegalStateException("couldn't find inline method $owner.$name$descriptor")
|
||||||
|
}
|
||||||
|
|
||||||
|
// If an `inline suspend fun` has a state machine, it should have a `$$forInline` version without one.
|
||||||
|
private fun getMethodNode(owner: Type, bytes: ByteArray, name: String, descriptor: String, isSuspend: Boolean) =
|
||||||
|
(if (isSuspend) getMethodNode(bytes, name + FOR_INLINE_SUFFIX, descriptor, owner) else null)
|
||||||
|
?: getMethodNode(bytes, name, descriptor, owner)
|
||||||
|
|||||||
+1
-1
@@ -106,7 +106,7 @@ class IrSourceCompilerForInline(
|
|||||||
|
|
||||||
override fun compileInlineFunction(jvmSignature: JvmMethodSignature): SMAPAndMethodNode =
|
override fun compileInlineFunction(jvmSignature: JvmMethodSignature): SMAPAndMethodNode =
|
||||||
callee.parentClassId?.let { containerId ->
|
callee.parentClassId?.let { containerId ->
|
||||||
InlineCodegen.loadCompiledInlineFunction(containerId, jvmSignature.asmMethod, callee.isSuspend, callee.hasMangledReturnType, state)
|
loadCompiledInlineFunction(containerId, jvmSignature.asmMethod, callee.isSuspend, callee.hasMangledReturnType, state)
|
||||||
} ?: 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()
|
||||||
|
|||||||
Reference in New Issue
Block a user