From ebf837c135050eacddcd6a072f5c2336f18e0e01 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 30 Jul 2021 08:32:37 +0300 Subject: [PATCH] JVM_IR disable IR and bytecode validation by default --- .../kotlin/codegen/optimization/MethodVerifier.kt | 4 +++- .../optimization/OptimizationMethodVisitor.kt | 4 ++-- .../kotlin/codegen/state/GenerationState.kt | 2 ++ .../common/arguments/K2JVMCompilerArguments.kt | 12 ++++++++++++ .../org/jetbrains/kotlin/cli/jvm/jvmArguments.kt | 3 +++ .../kotlin/config/JVMConfigurationKeys.java | 8 +++++++- .../org/jetbrains/kotlin/backend/jvm/JvmLower.kt | 8 ++++---- .../kotlin/backend/jvm/lower/irValidation.kt | 15 +++++++++++++++ compiler/testData/cli/jvm/extraHelp.out | 2 ++ .../configuration/JvmEnvironmentConfigurator.kt | 3 +++ 10 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/irValidation.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/MethodVerifier.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/MethodVerifier.kt index 0796f110112..39f776125c1 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/MethodVerifier.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/MethodVerifier.kt @@ -17,11 +17,13 @@ package org.jetbrains.kotlin.codegen.optimization import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer +import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.org.objectweb.asm.tree.MethodNode import org.jetbrains.org.objectweb.asm.tree.analysis.BasicVerifier -class MethodVerifier(private val checkPoint: String) : MethodTransformer() { +class MethodVerifier(private val checkPoint: String, private val generationState: GenerationState) : MethodTransformer() { override fun transform(internalClassName: String, methodNode: MethodNode) { + if (!generationState.shouldValidateBytecode) return try { analyze(internalClassName, methodNode, BasicVerifier()) } catch (e: Throwable) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/OptimizationMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/OptimizationMethodVisitor.kt index 43e0361e189..4cc6898f7bf 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/OptimizationMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/OptimizationMethodVisitor.kt @@ -41,7 +41,7 @@ class OptimizationMethodVisitor( val normalizationMethodTransformer = CompositeMethodTransformer( FixStackWithLabelNormalizationMethodTransformer(), - MethodVerifier("AFTER mandatory stack transformations") + MethodVerifier("AFTER mandatory stack transformations", generationState) ) val optimizationTransformer = CompositeMethodTransformer( @@ -55,7 +55,7 @@ class OptimizationMethodVisitor( DeadCodeEliminationMethodTransformer(), RedundantGotoMethodTransformer(), RedundantNopsCleanupMethodTransformer(), - MethodVerifier("AFTER optimizations") + MethodVerifier("AFTER optimizations", generationState) ) override fun performTransformations(methodNode: MethodNode) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt index e7dc2da10f3..850a6524ae2 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/GenerationState.kt @@ -299,6 +299,8 @@ class GenerationState private constructor( !configuration.getBoolean(JVMConfigurationKeys.NO_UNIFIED_NULL_CHECKS) val functionsWithInlineClassReturnTypesMangled: Boolean = languageVersionSettings.supportsFeature(LanguageFeature.MangleClassMembersReturningInlineClasses) + val shouldValidateIr = configuration.getBoolean(JVMConfigurationKeys.VALIDATE_IR) + val shouldValidateBytecode = configuration.getBoolean(JVMConfigurationKeys.VALIDATE_BYTECODE) val rootContext: CodegenContext<*> = RootContext(this) diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt index 45b4a6f34fd..933fae47f90 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt @@ -511,6 +511,18 @@ default: `indy-with-constants` for JVM target 9 or greater, `inline` otherwise"" ) var serializeIr: Boolean by FreezableVar(false) + @Argument( + value = "-Xvalidate-ir", + description = "Validate IR before and after lowering" + ) + var validateIr: Boolean by FreezableVar(false) + + @Argument( + value = "-Xvalidate-bytecode", + description = "Validate generated JVM bytecode before and after optimizations" + ) + var validateBytecode: Boolean by FreezableVar(false) + override fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap, Any> { val result = super.configureAnalysisFlags(collector, languageVersion) result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt index f403032344c..30e92def195 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/jvmArguments.kt @@ -254,6 +254,9 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr put(JVMConfigurationKeys.SERIALIZE_IR, arguments.serializeIr) + put(JVMConfigurationKeys.VALIDATE_IR, arguments.validateIr) + put(JVMConfigurationKeys.VALIDATE_BYTECODE, arguments.validateBytecode) + if (!JVMConstructorCallNormalizationMode.isSupportedValue(arguments.constructorCallNormalizationMode)) { messageCollector.report( ERROR, diff --git a/compiler/config.jvm/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java b/compiler/config.jvm/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java index a76435685b0..c4fbadfc13d 100644 --- a/compiler/config.jvm/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java +++ b/compiler/config.jvm/src/org/jetbrains/kotlin/config/JVMConfigurationKeys.java @@ -157,5 +157,11 @@ public class JVMConfigurationKeys { CompilerConfigurationKey.create("Don't automatically include kotlin-reflect.jar into the output if the output is a jar"); public static final CompilerConfigurationKey SERIALIZE_IR = - CompilerConfigurationKey.create("serialize IR to class metadata"); + CompilerConfigurationKey.create("Serialize IR to class metadata"); + + public static final CompilerConfigurationKey VALIDATE_IR = + CompilerConfigurationKey.create("Validate IR"); + + public static final CompilerConfigurationKey VALIDATE_BYTECODE = + CompilerConfigurationKey.create("Validate generated JVM bytecode"); } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 0c971f36f12..9fc336a0c47 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -41,14 +41,14 @@ private class PatchDeclarationParents : FileLoweringPass { } } -private val validateIrBeforeLowering = makeCustomPhase( - { context, module -> validationCallback(context, module, checkProperties = true) }, +private val validateIrBeforeLowering = makeCustomPhase( + ::validateIr, name = "ValidateIrBeforeLowering", description = "Validate IR before lowering" ) -private val validateIrAfterLowering = makeCustomPhase( - { context, module -> validationCallback(context, module, checkProperties = true) }, +private val validateIrAfterLowering = makeCustomPhase( + ::validateIr, name = "ValidateIrAfterLowering", description = "Validate IR after lowering" ) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/irValidation.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/irValidation.kt new file mode 100644 index 00000000000..32cbfd517f5 --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/irValidation.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2010-2021 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.backend.jvm.lower + +import org.jetbrains.kotlin.backend.common.phaser.validationCallback +import org.jetbrains.kotlin.backend.jvm.JvmBackendContext +import org.jetbrains.kotlin.ir.declarations.IrModuleFragment + +fun validateIr(context: JvmBackendContext, module: IrModuleFragment) { + if (!context.state.shouldValidateIr) return + validationCallback(context, module, checkProperties = true) +} \ No newline at end of file diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index a5764ab19aa..6a2d85845be 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -146,6 +146,8 @@ where advanced options include: -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 + -Xvalidate-bytecode Validate generated JVM bytecode before and after optimizations + -Xvalidate-ir Validate IR before and after lowering -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 -Xbuiltins-from-sources Compile builtIns from sources diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt index 26e4b16b982..a4123251f58 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt @@ -255,6 +255,9 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig if (CodegenTestDirectives.DUMP_IR_FOR_GIVEN_PHASES in module.directives) { configuration.putCustomPhaseConfigWithEnabledDump(module) } + + configuration.put(JVMConfigurationKeys.VALIDATE_IR, true) + configuration.put(JVMConfigurationKeys.VALIDATE_BYTECODE, true) } private fun addJavaSourceRootsByJavaModules(configuration: CompilerConfiguration, moduleInfoFiles: List) {