Add flag to disable new spilled variable type analysis
This commit is contained in:
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.codegen.context.MethodContext
|
|||||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION
|
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION
|
||||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension
|
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
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.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
@@ -512,7 +513,8 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
containingClassInternalName = v.thisName,
|
containingClassInternalName = v.thisName,
|
||||||
isForNamedFunction = false,
|
isForNamedFunction = false,
|
||||||
languageVersionSettings = languageVersionSettings,
|
languageVersionSettings = languageVersionSettings,
|
||||||
disableTailCallOptimizationForFunctionReturningUnit = false
|
disableTailCallOptimizationForFunctionReturningUnit = false,
|
||||||
|
useOldSpilledVarTypeAnalysis = state.configuration.getBoolean(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS)
|
||||||
)
|
)
|
||||||
val maybeWithForInline = if (forInline)
|
val maybeWithForInline = if (forInline)
|
||||||
SuspendForInlineCopyingMethodVisitor(stateMachineBuilder, access, name, desc, functionCodegen::newMethod)
|
SuspendForInlineCopyingMethodVisitor(stateMachineBuilder, access, name, desc, functionCodegen::newMethod)
|
||||||
|
|||||||
+8
-7
@@ -5,14 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.coroutines
|
package org.jetbrains.kotlin.codegen.coroutines
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
|
||||||
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.*
|
import org.jetbrains.kotlin.codegen.inline.*
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.*
|
import org.jetbrains.kotlin.codegen.optimization.common.*
|
||||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer
|
import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer
|
||||||
import org.jetbrains.kotlin.codegen.linkWithLabel
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
@@ -65,7 +61,9 @@ class CoroutineTransformerMethodVisitor(
|
|||||||
// May differ from containingClassInternalName in case of DefaultImpls
|
// May differ from containingClassInternalName in case of DefaultImpls
|
||||||
private val internalNameForDispatchReceiver: String? = null,
|
private val internalNameForDispatchReceiver: String? = null,
|
||||||
// JVM_IR backend generates $completion, while old backend does not
|
// JVM_IR backend generates $completion, while old backend does not
|
||||||
private val putContinuationParameterToLvt: Boolean = true
|
private val putContinuationParameterToLvt: Boolean = true,
|
||||||
|
// New SourceInterpreter-less analyser can be somewhat unstable, disable it
|
||||||
|
private val useOldSpilledVarTypeAnalysis: Boolean = false
|
||||||
) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) {
|
) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) {
|
||||||
|
|
||||||
private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState)
|
private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState)
|
||||||
@@ -594,7 +592,10 @@ class CoroutineTransformerMethodVisitor(
|
|||||||
|
|
||||||
private fun spillVariables(suspensionPoints: List<SuspensionPoint>, methodNode: MethodNode): List<List<SpilledVariableDescriptor>> {
|
private fun spillVariables(suspensionPoints: List<SuspensionPoint>, methodNode: MethodNode): List<List<SpilledVariableDescriptor>> {
|
||||||
val instructions = methodNode.instructions
|
val instructions = methodNode.instructions
|
||||||
val frames = performSpilledVariableFieldTypesAnalysis(methodNode, containingClassInternalName)
|
val frames =
|
||||||
|
if (useOldSpilledVarTypeAnalysis) performRefinedTypeAnalysis(methodNode, containingClassInternalName)
|
||||||
|
else performSpilledVariableFieldTypesAnalysis(methodNode, containingClassInternalName)
|
||||||
|
|
||||||
fun AbstractInsnNode.index() = instructions.indexOf(this)
|
fun AbstractInsnNode.index() = instructions.indexOf(this)
|
||||||
|
|
||||||
// We postpone these actions because they change instruction indices that we use when obtaining frames
|
// We postpone these actions because they change instruction indices that we use when obtaining frames
|
||||||
|
|||||||
+8
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
|||||||
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.tree.*
|
import org.jetbrains.org.objectweb.asm.tree.*
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
||||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter
|
import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter
|
||||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Value
|
import org.jetbrains.org.objectweb.asm.tree.analysis.Value
|
||||||
@@ -359,3 +360,10 @@ internal fun performSpilledVariableFieldTypesAnalysis(
|
|||||||
thisName: String
|
thisName: String
|
||||||
): Array<out Frame<SpilledVariableFieldTypeValue>?> =
|
): Array<out Frame<SpilledVariableFieldTypeValue>?> =
|
||||||
MethodAnalyzer(thisName, methodNode, SpilledVariableFieldTypesInterpreter(methodNode)).analyze()
|
MethodAnalyzer(thisName, methodNode, SpilledVariableFieldTypesInterpreter(methodNode)).analyze()
|
||||||
|
|
||||||
|
internal val Value.type: Type?
|
||||||
|
get() = when (this) {
|
||||||
|
is BasicValue -> type
|
||||||
|
is SpilledVariableFieldTypeValue -> type
|
||||||
|
else -> error("Unexpected type of $this")
|
||||||
|
}
|
||||||
+3
-1
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.codegen.inline.addFakeContinuationConstructorCallMar
|
|||||||
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.inline.preprocessSuspendMarkers
|
import org.jetbrains.kotlin.codegen.inline.preprocessSuspendMarkers
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.JVMConstructorCallNormalizationMode
|
import org.jetbrains.kotlin.config.JVMConstructorCallNormalizationMode
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||||
@@ -95,7 +96,8 @@ class SuspendFunctionGenerationStrategy(
|
|||||||
languageVersionSettings = languageVersionSettings,
|
languageVersionSettings = languageVersionSettings,
|
||||||
disableTailCallOptimizationForFunctionReturningUnit = originalSuspendDescriptor.returnType?.isUnit() == true &&
|
disableTailCallOptimizationForFunctionReturningUnit = originalSuspendDescriptor.returnType?.isUnit() == true &&
|
||||||
originalSuspendDescriptor.overriddenDescriptors.isNotEmpty() &&
|
originalSuspendDescriptor.overriddenDescriptors.isNotEmpty() &&
|
||||||
!originalSuspendDescriptor.allOverriddenFunctionsReturnUnit()
|
!originalSuspendDescriptor.allOverriddenFunctionsReturnUnit(),
|
||||||
|
useOldSpilledVarTypeAnalysis = state.configuration.getBoolean(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.codegen.coroutines.*
|
|||||||
import org.jetbrains.kotlin.codegen.inline.*
|
import org.jetbrains.kotlin.codegen.inline.*
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||||
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
@@ -95,7 +96,8 @@ class CoroutineTransformer(
|
|||||||
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||||
containingClassInternalName = classBuilder.thisName,
|
containingClassInternalName = classBuilder.thisName,
|
||||||
isForNamedFunction = false,
|
isForNamedFunction = false,
|
||||||
disableTailCallOptimizationForFunctionReturningUnit = false
|
disableTailCallOptimizationForFunctionReturningUnit = false,
|
||||||
|
useOldSpilledVarTypeAnalysis = state.configuration.getBoolean(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (generateForInline)
|
if (generateForInline)
|
||||||
@@ -131,7 +133,8 @@ class CoroutineTransformer(
|
|||||||
needDispatchReceiver = true,
|
needDispatchReceiver = true,
|
||||||
internalNameForDispatchReceiver = classBuilder.thisName,
|
internalNameForDispatchReceiver = classBuilder.thisName,
|
||||||
disableTailCallOptimizationForFunctionReturningUnit = disableTailCallOptimization,
|
disableTailCallOptimizationForFunctionReturningUnit = disableTailCallOptimization,
|
||||||
putContinuationParameterToLvt = !state.isIrBackend
|
putContinuationParameterToLvt = !state.isIrBackend,
|
||||||
|
useOldSpilledVarTypeAnalysis = state.configuration.getBoolean(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (generateForInline)
|
if (generateForInline)
|
||||||
|
|||||||
+6
@@ -369,6 +369,12 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
|||||||
)
|
)
|
||||||
var repeatCompileModules: String? by NullableStringFreezableVar(null)
|
var repeatCompileModules: String? by NullableStringFreezableVar(null)
|
||||||
|
|
||||||
|
@Argument(
|
||||||
|
value = "-Xuse-old-spilled-var-type-analysis",
|
||||||
|
description = "Use old, SourceInterpreter-based analysis for fields, used for spilled variables in coroutines"
|
||||||
|
)
|
||||||
|
var useOldSpilledVarTypeAnalysis: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
||||||
val result = super.configureAnalysisFlags(collector)
|
val result = super.configureAnalysisFlags(collector)
|
||||||
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics
|
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr
|
|||||||
|
|
||||||
put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage)
|
put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage)
|
||||||
put(JVMConfigurationKeys.USE_SINGLE_MODULE, arguments.singleModule)
|
put(JVMConfigurationKeys.USE_SINGLE_MODULE, arguments.singleModule)
|
||||||
|
put(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS, arguments.useOldSpilledVarTypeAnalysis)
|
||||||
|
|
||||||
arguments.declarationsOutputPath?.let { put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, it) }
|
arguments.declarationsOutputPath?.let { put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, it) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,4 +122,7 @@ public class JVMConfigurationKeys {
|
|||||||
|
|
||||||
public static final CompilerConfigurationKey<Boolean> NO_KOTLIN_NOTHING_VALUE_EXCEPTION =
|
public static final CompilerConfigurationKey<Boolean> NO_KOTLIN_NOTHING_VALUE_EXCEPTION =
|
||||||
CompilerConfigurationKey.create("Do not use KotlinNothingValueException available since 1.4");
|
CompilerConfigurationKey.create("Do not use KotlinNothingValueException available since 1.4");
|
||||||
|
|
||||||
|
public static final CompilerConfigurationKey<Boolean> USE_OLD_SPILLED_VAR_TYPE_ANALYSIS =
|
||||||
|
CompilerConfigurationKey.create("Use old, SourceInterpreter-based analysis for fields, used for spilled variables in coroutines");
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.codegen.coroutines.INVOKE_SUSPEND_METHOD_NAME
|
|||||||
import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_IMPL_NAME_SUFFIX
|
import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_IMPL_NAME_SUFFIX
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.reportSuspensionPointInsideMonitor
|
import org.jetbrains.kotlin.codegen.coroutines.reportSuspensionPointInsideMonitor
|
||||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||||
|
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -64,7 +65,8 @@ internal fun MethodNode.acceptWithStateMachine(
|
|||||||
putContinuationParameterToLvt = false,
|
putContinuationParameterToLvt = false,
|
||||||
disableTailCallOptimizationForFunctionReturningUnit = irFunction.isSuspend && irFunction.suspendFunctionOriginal().let {
|
disableTailCallOptimizationForFunctionReturningUnit = irFunction.isSuspend && irFunction.suspendFunctionOriginal().let {
|
||||||
it.returnType.isUnit() && it.anyOfOverriddenFunctionsReturnsNonUnit()
|
it.returnType.isUnit() && it.anyOfOverriddenFunctionsReturnsNonUnit()
|
||||||
}
|
},
|
||||||
|
useOldSpilledVarTypeAnalysis = state.configuration.getBoolean(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS)
|
||||||
)
|
)
|
||||||
accept(visitor)
|
accept(visitor)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -100,6 +100,8 @@ where advanced options include:
|
|||||||
-Xuse-javac Use javac for Java source and class files analysis
|
-Xuse-javac Use javac for Java source and class files analysis
|
||||||
-Xuse-old-class-files-reading Use old class files reading implementation. This may slow down the build and cause problems with Groovy interop.
|
-Xuse-old-class-files-reading Use old class files reading implementation. This may slow down the build and cause problems with Groovy interop.
|
||||||
Should be used in case of problems with the new implementation
|
Should be used in case of problems with the new implementation
|
||||||
|
-Xuse-old-spilled-var-type-analysis
|
||||||
|
Use old, SourceInterpreter-based analysis for fields, used for spilled variables in coroutines
|
||||||
-Xuse-type-table Use type table in metadata serialization
|
-Xuse-type-table Use type table in metadata serialization
|
||||||
-Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info
|
-Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info
|
||||||
-Xallow-result-return-type Allow compiling code when `kotlin.Result` is used as a return type
|
-Xallow-result-return-type Allow compiling code when `kotlin.Result` is used as a return type
|
||||||
|
|||||||
Reference in New Issue
Block a user