[K/N] Move calls checker into separate module ^KT-62091

This commit is contained in:
Alexander Shabalin
2024-01-03 14:02:36 +01:00
committed by Space Team
parent 8cd87059c8
commit 3f2584bb02
15 changed files with 112 additions and 64 deletions
@@ -283,7 +283,7 @@ The default value is 1."""
var printBitCode: Boolean = false var printBitCode: Boolean = false
@Argument(value = "-Xcheck-state-at-external-calls", description = "Ensure that all calls of possibly long external functions are done in the native thread state.") @Argument(value = "-Xcheck-state-at-external-calls", description = "Ensure that all calls of possibly long external functions are done in the native thread state.")
var checkExternalCalls: Boolean = false var checkExternalCalls: Boolean? = null
@Argument(value = "-Xprint-ir", deprecatedName = "--print_ir", description = "Print IR.") @Argument(value = "-Xprint-ir", deprecatedName = "--print_ir", description = "Print IR.")
var printIr: Boolean = false var printIr: Boolean = false
@@ -15,6 +15,8 @@ import kotlin.properties.ReadOnlyProperty
object BinaryOptions : BinaryOptionRegistry() { object BinaryOptions : BinaryOptionRegistry() {
val runtimeAssertionsMode by option<RuntimeAssertsMode>() val runtimeAssertionsMode by option<RuntimeAssertsMode>()
val checkStateAtExternalCalls by booleanOption()
val memoryModel by option<MemoryModel>() val memoryModel by option<MemoryModel>()
val freezing by option<Freezing>() val freezing by option<Freezing>()
@@ -95,6 +95,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
private val defaultGC get() = GC.PARALLEL_MARK_CONCURRENT_SWEEP private val defaultGC get() = GC.PARALLEL_MARK_CONCURRENT_SWEEP
val gc: GC get() = configuration.get(BinaryOptions.gc) ?: defaultGC val gc: GC get() = configuration.get(BinaryOptions.gc) ?: defaultGC
val runtimeAssertsMode: RuntimeAssertsMode get() = configuration.get(BinaryOptions.runtimeAssertionsMode) ?: RuntimeAssertsMode.IGNORE val runtimeAssertsMode: RuntimeAssertsMode get() = configuration.get(BinaryOptions.runtimeAssertionsMode) ?: RuntimeAssertsMode.IGNORE
val checkStateAtExternalCalls: Boolean get() = configuration.get(BinaryOptions.checkStateAtExternalCalls) ?: false
private val defaultDisableMmap get() = target.family == Family.MINGW private val defaultDisableMmap get() = target.family == Family.MINGW
val disableMmap: Boolean by lazy { val disableMmap: Boolean by lazy {
when (configuration.get(BinaryOptions.disableMmap)) { when (configuration.get(BinaryOptions.disableMmap)) {
@@ -400,6 +401,10 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
add("custom_alloc.bc") add("custom_alloc.bc")
} }
} }
when (checkStateAtExternalCalls) {
true -> add("impl_externalCallsChecker.bc")
false -> add("noop_externalCallsChecker.bc")
}
}.map { }.map {
File(distribution.defaultNatives(target)).child(it).absolutePath File(distribution.defaultNatives(target)).child(it).absolutePath
} }
@@ -523,6 +528,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
optimizationsEnabled -> "for optimized compilation" optimizationsEnabled -> "for optimized compilation"
sanitizer != null -> "with sanitizers enabled" sanitizer != null -> "with sanitizers enabled"
runtimeLogsEnabled -> "with runtime logs" runtimeLogsEnabled -> "with runtime logs"
checkStateAtExternalCalls -> "with external calls state checker"
else -> null else -> null
} }
@@ -101,8 +101,6 @@ class KonanConfigKeys {
= CompilerConfigurationKey.create("export KDoc into klib and framework") = CompilerConfigurationKey.create("export KDoc into klib and framework")
val PRINT_BITCODE: CompilerConfigurationKey<Boolean> val PRINT_BITCODE: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("print bitcode") = CompilerConfigurationKey.create("print bitcode")
val CHECK_EXTERNAL_CALLS: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("check external calls")
val PRINT_IR: CompilerConfigurationKey<Boolean> val PRINT_IR: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("print ir") = CompilerConfigurationKey.create("print ir")
val PRINT_FILES: CompilerConfigurationKey<Boolean> val PRINT_FILES: CompilerConfigurationKey<Boolean>
@@ -108,7 +108,6 @@ fun CompilerConfiguration.setupFromArguments(arguments: K2NativeCompilerArgument
put(PRINT_IR, arguments.printIr) put(PRINT_IR, arguments.printIr)
put(PRINT_BITCODE, arguments.printBitCode) put(PRINT_BITCODE, arguments.printBitCode)
put(CHECK_EXTERNAL_CALLS, arguments.checkExternalCalls)
put(PRINT_FILES, arguments.printFiles) put(PRINT_FILES, arguments.printFiles)
put(PURGE_USER_LIBS, arguments.purgeUserLibs) put(PURGE_USER_LIBS, arguments.purgeUserLibs)
@@ -242,6 +241,14 @@ fun CompilerConfiguration.setupFromArguments(arguments: K2NativeCompilerArgument
putIfNotNull(BinaryOptions.gc, gcFromArgument) putIfNotNull(BinaryOptions.gc, gcFromArgument)
} }
if (arguments.checkExternalCalls != null) {
report(WARNING, "-Xcheck-state-at-external-calls compiler argument is deprecated. Use -Xbinary=checkStateAtExternalCalls=true instead")
}
// TODO: revise priority and/or report conflicting values.
if (get(BinaryOptions.checkStateAtExternalCalls) == null) {
putIfNotNull(BinaryOptions.checkStateAtExternalCalls, arguments.checkExternalCalls)
}
putIfNotNull(PROPERTY_LAZY_INITIALIZATION, when (arguments.propertyLazyInitialization) { putIfNotNull(PROPERTY_LAZY_INITIALIZATION, when (arguments.propertyLazyInitialization) {
null -> null null -> null
"enable" -> true "enable" -> true
@@ -249,7 +249,7 @@ internal data class ModuleCompilationOutput(
*/ */
internal fun PhaseEngine<NativeGenerationState>.compileModule(module: IrModuleFragment, bitcodeFile: java.io.File, cExportFiles: CExportFiles?) { internal fun PhaseEngine<NativeGenerationState>.compileModule(module: IrModuleFragment, bitcodeFile: java.io.File, cExportFiles: CExportFiles?) {
runBackendCodegen(module, cExportFiles) runBackendCodegen(module, cExportFiles)
val checkExternalCalls = context.config.configuration.getBoolean(KonanConfigKeys.CHECK_EXTERNAL_CALLS) val checkExternalCalls = context.config.checkStateAtExternalCalls
if (checkExternalCalls) { if (checkExternalCalls) {
runPhase(CheckExternalCallsPhase) runPhase(CheckExternalCallsPhase)
} }
+60 -43
View File
@@ -42,6 +42,7 @@ val targetList: List<String> by project
bitcode { bitcode {
allTargets { allTargets {
module("main") { module("main") {
headersDirs.from("src/externalCallsChecker/common/cpp")
sourceSets { sourceSets {
main { main {
// TODO: Split out out `base` module and merge it together with `main` into `runtime.bc` // TODO: Split out out `base` module and merge it together with `main` into `runtime.bc`
@@ -133,21 +134,21 @@ bitcode {
} }
module("compiler_interface") { module("compiler_interface") {
headersDirs.from(files("src/main/cpp")) headersDirs.from(files("src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
} }
} }
module("launcher") { module("launcher") {
headersDirs.from(files("src/main/cpp")) headersDirs.from(files("src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
} }
} }
module("debug") { module("debug") {
headersDirs.from(files("src/main/cpp")) headersDirs.from(files("src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
} }
@@ -155,7 +156,7 @@ bitcode {
module("common_alloc") { module("common_alloc") {
srcRoot.set(layout.projectDirectory.dir("src/alloc/common")) srcRoot.set(layout.projectDirectory.dir("src/alloc/common"))
headersDirs.from(files("src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp")) headersDirs.from(files("src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
} }
@@ -163,7 +164,7 @@ bitcode {
module("std_alloc") { module("std_alloc") {
srcRoot.set(layout.projectDirectory.dir("src/alloc/std")) srcRoot.set(layout.projectDirectory.dir("src/alloc/std"))
headersDirs.from(files("src/alloc/common/cpp", "src/alloc/legacy/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/alloc/legacy/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
} }
@@ -171,7 +172,7 @@ bitcode {
module("custom_alloc") { module("custom_alloc") {
srcRoot.set(layout.projectDirectory.dir("src/alloc/custom")) srcRoot.set(layout.projectDirectory.dir("src/alloc/custom"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
test {} test {}
@@ -183,7 +184,7 @@ bitcode {
module("mimalloc_alloc") { module("mimalloc_alloc") {
srcRoot.set(layout.projectDirectory.dir("src/alloc/mimalloc")) srcRoot.set(layout.projectDirectory.dir("src/alloc/mimalloc"))
headersDirs.from(files("src/mimalloc/c/include", "src/alloc/common/cpp", "src/alloc/legacy/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp")) headersDirs.from(files("src/mimalloc/c/include", "src/alloc/common/cpp", "src/alloc/legacy/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
} }
@@ -193,7 +194,7 @@ bitcode {
module("legacy_alloc") { module("legacy_alloc") {
srcRoot.set(layout.projectDirectory.dir("src/alloc/legacy")) srcRoot.set(layout.projectDirectory.dir("src/alloc/legacy"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
test {} test {}
@@ -203,7 +204,7 @@ bitcode {
module("exceptionsSupport") { module("exceptionsSupport") {
srcRoot.set(layout.projectDirectory.dir("src/exceptions_support")) srcRoot.set(layout.projectDirectory.dir("src/exceptions_support"))
headersDirs.from(files("src/main/cpp")) headersDirs.from(files("src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
} }
@@ -211,7 +212,7 @@ bitcode {
module("source_info_core_symbolication") { module("source_info_core_symbolication") {
srcRoot.set(layout.projectDirectory.dir("src/source_info/core_symbolication")) srcRoot.set(layout.projectDirectory.dir("src/source_info/core_symbolication"))
headersDirs.from(files("src/main/cpp")) headersDirs.from(files("src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
} }
@@ -221,7 +222,7 @@ bitcode {
module("source_info_libbacktrace") { module("source_info_libbacktrace") {
srcRoot.set(layout.projectDirectory.dir("src/source_info/libbacktrace")) srcRoot.set(layout.projectDirectory.dir("src/source_info/libbacktrace"))
headersDirs.from(files("src/main/cpp", "src/libbacktrace/c/include")) headersDirs.from(files("src/externalCallsChecker/common/cpp", "src/main/cpp", "src/libbacktrace/c/include"))
sourceSets { sourceSets {
main {} main {}
} }
@@ -230,14 +231,14 @@ bitcode {
} }
module("objc") { module("objc") {
headersDirs.from(files("src/main/cpp")) headersDirs.from(files("src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
} }
} }
module("test_support") { module("test_support") {
headersDirs.from(files("src/main/cpp")) headersDirs.from(files("src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
testFixtures { testFixtures {
inputFiles.include("**/*.cpp", "**/*.mm") inputFiles.include("**/*.cpp", "**/*.mm")
@@ -246,7 +247,7 @@ bitcode {
} }
module("mm") { module("mm") {
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/main/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
testFixtures {} testFixtures {}
@@ -256,7 +257,7 @@ bitcode {
module("common_gc") { module("common_gc") {
srcRoot.set(layout.projectDirectory.dir("src/gc/common")) srcRoot.set(layout.projectDirectory.dir("src/gc/common"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/mm/cpp", "src/main/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
test {} test {}
@@ -265,7 +266,7 @@ bitcode {
module("noop_gc") { module("noop_gc") {
srcRoot.set(layout.projectDirectory.dir("src/gc/noop")) srcRoot.set(layout.projectDirectory.dir("src/gc/noop"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp", "src/alloc/legacy/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp", "src/alloc/legacy/cpp"))
sourceSets { sourceSets {
main {} main {}
} }
@@ -273,7 +274,7 @@ bitcode {
module("noop_gc_custom") { module("noop_gc_custom") {
srcRoot.set(layout.projectDirectory.dir("src/gc/noop")) srcRoot.set(layout.projectDirectory.dir("src/gc/noop"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp", "src/alloc/custom/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp", "src/alloc/custom/cpp"))
sourceSets { sourceSets {
main {} main {}
} }
@@ -283,7 +284,7 @@ bitcode {
module("same_thread_ms_gc") { module("same_thread_ms_gc") {
srcRoot.set(layout.projectDirectory.dir("src/gc/stms")) srcRoot.set(layout.projectDirectory.dir("src/gc/stms"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp", "src/alloc/legacy/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp", "src/alloc/legacy/cpp"))
sourceSets { sourceSets {
main {} main {}
test {} test {}
@@ -292,7 +293,7 @@ bitcode {
module("same_thread_ms_gc_custom") { module("same_thread_ms_gc_custom") {
srcRoot.set(layout.projectDirectory.dir("src/gc/stms")) srcRoot.set(layout.projectDirectory.dir("src/gc/stms"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp", "src/alloc/custom/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp", "src/alloc/custom/cpp"))
sourceSets { sourceSets {
main {} main {}
test {} test {}
@@ -303,7 +304,7 @@ bitcode {
module("pmcs_gc") { module("pmcs_gc") {
srcRoot.set(layout.projectDirectory.dir("src/gc/pmcs")) srcRoot.set(layout.projectDirectory.dir("src/gc/pmcs"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp", "src/alloc/legacy/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp", "src/alloc/legacy/cpp"))
sourceSets { sourceSets {
main {} main {}
test {} test {}
@@ -312,7 +313,7 @@ bitcode {
module("pmcs_gc_custom") { module("pmcs_gc_custom") {
srcRoot.set(layout.projectDirectory.dir("src/gc/pmcs")) srcRoot.set(layout.projectDirectory.dir("src/gc/pmcs"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp", "src/alloc/custom/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp", "src/alloc/custom/cpp"))
sourceSets { sourceSets {
main {} main {}
test {} test {}
@@ -323,7 +324,7 @@ bitcode {
module("concurrent_ms_gc") { module("concurrent_ms_gc") {
srcRoot.set(layout.projectDirectory.dir("src/gc/cms")) srcRoot.set(layout.projectDirectory.dir("src/gc/cms"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp", "src/alloc/legacy/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp", "src/alloc/legacy/cpp"))
sourceSets { sourceSets {
main {} main {}
test {} test {}
@@ -332,7 +333,7 @@ bitcode {
module("concurrent_ms_gc_custom") { module("concurrent_ms_gc_custom") {
srcRoot.set(layout.projectDirectory.dir("src/gc/cms")) srcRoot.set(layout.projectDirectory.dir("src/gc/cms"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp", "src/alloc/custom/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp", "src/alloc/custom/cpp"))
sourceSets { sourceSets {
main {} main {}
test {} test {}
@@ -343,7 +344,7 @@ bitcode {
module("common_gcScheduler") { module("common_gcScheduler") {
srcRoot.set(layout.projectDirectory.dir("src/gcScheduler/common")) srcRoot.set(layout.projectDirectory.dir("src/gcScheduler/common"))
headersDirs.from(files("src/alloc/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
test {} test {}
@@ -352,7 +353,7 @@ bitcode {
module("manual_gcScheduler") { module("manual_gcScheduler") {
srcRoot.set(layout.projectDirectory.dir("src/gcScheduler/manual")) srcRoot.set(layout.projectDirectory.dir("src/gcScheduler/manual"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
} }
@@ -360,7 +361,7 @@ bitcode {
module("adaptive_gcScheduler") { module("adaptive_gcScheduler") {
srcRoot.set(layout.projectDirectory.dir("src/gcScheduler/adaptive")) srcRoot.set(layout.projectDirectory.dir("src/gcScheduler/adaptive"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
test {} test {}
@@ -369,15 +370,31 @@ bitcode {
module("aggressive_gcScheduler") { module("aggressive_gcScheduler") {
srcRoot.set(layout.projectDirectory.dir("src/gcScheduler/aggressive")) srcRoot.set(layout.projectDirectory.dir("src/gcScheduler/aggressive"))
headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/main/cpp")) headersDirs.from(files("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
test {} test {}
} }
} }
module("impl_externalCallsChecker") {
srcRoot.set(layout.projectDirectory.dir("src/externalCallsChecker/impl"))
headersDirs.from("src/alloc/common/cpp", "src/gcScheduler/common/cpp", "src/gc/common/cpp", "src/mm/cpp", "src/externalCallsChecker/common/cpp", "src/main/cpp")
sourceSets {
main {}
}
}
module("noop_externalCallsChecker") {
srcRoot.set(layout.projectDirectory.dir("src/externalCallsChecker/noop"))
headersDirs.from("src/externalCallsChecker/common/cpp", "src/main/cpp")
sourceSets {
main {}
}
}
module("xctest_launcher") { module("xctest_launcher") {
headersDirs.from(files("src/main/cpp")) headersDirs.from(files("src/externalCallsChecker/common/cpp", "src/main/cpp"))
sourceSets { sourceSets {
main {} main {}
@@ -387,69 +404,69 @@ bitcode {
testsGroup("custom_alloc_runtime_tests") { testsGroup("custom_alloc_runtime_tests") {
testedModules.addAll("custom_alloc") testedModules.addAll("custom_alloc")
testSupportModules.addAll("main", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "concurrent_ms_gc_custom", "objc") testSupportModules.addAll("main", "noop_externalCallsChecker", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "concurrent_ms_gc_custom", "objc")
} }
testsGroup("experimentalMM_stms_mimalloc_runtime_tests") { testsGroup("experimentalMM_stms_mimalloc_runtime_tests") {
testedModules.addAll("main", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "same_thread_ms_gc", "mimalloc", "mimalloc_alloc", "legacy_alloc", "objc") testedModules.addAll("main", "noop_externalCallsChecker", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "same_thread_ms_gc", "mimalloc", "mimalloc_alloc", "legacy_alloc", "objc")
} }
testsGroup("experimentalMM_stms_std_alloc_runtime_tests") { testsGroup("experimentalMM_stms_std_alloc_runtime_tests") {
testedModules.addAll("main", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "same_thread_ms_gc", "std_alloc", "legacy_alloc", "objc") testedModules.addAll("main", "noop_externalCallsChecker", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "same_thread_ms_gc", "std_alloc", "legacy_alloc", "objc")
} }
testsGroup("experimentalMM_stms_custom_alloc_runtime_tests") { testsGroup("experimentalMM_stms_custom_alloc_runtime_tests") {
testedModules.addAll("mm", "same_thread_ms_gc_custom") testedModules.addAll("mm", "same_thread_ms_gc_custom")
testSupportModules.addAll("main", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "custom_alloc", "objc") testSupportModules.addAll("main", "noop_externalCallsChecker", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "custom_alloc", "objc")
} }
testsGroup("experimentalMM_pmcs_mimalloc_runtime_tests") { testsGroup("experimentalMM_pmcs_mimalloc_runtime_tests") {
testedModules.addAll("main", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "pmcs_gc", "mimalloc", "mimalloc_alloc", "legacy_alloc", "objc") testedModules.addAll("main", "noop_externalCallsChecker", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "pmcs_gc", "mimalloc", "mimalloc_alloc", "legacy_alloc", "objc")
} }
testsGroup("experimentalMM_pmcs_std_alloc_runtime_tests") { testsGroup("experimentalMM_pmcs_std_alloc_runtime_tests") {
testedModules.addAll("main", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "pmcs_gc", "std_alloc", "legacy_alloc", "objc") testedModules.addAll("main", "noop_externalCallsChecker", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "pmcs_gc", "std_alloc", "legacy_alloc", "objc")
} }
testsGroup("experimentalMM_pmcs_custom_alloc_runtime_tests") { testsGroup("experimentalMM_pmcs_custom_alloc_runtime_tests") {
testedModules.addAll("mm", "pmcs_gc_custom") testedModules.addAll("mm", "pmcs_gc_custom")
testSupportModules.addAll("main", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "custom_alloc", "objc") testSupportModules.addAll("main", "noop_externalCallsChecker", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "custom_alloc", "objc")
} }
testsGroup("experimentalMM_cms_mimalloc_runtime_tests") { testsGroup("experimentalMM_cms_mimalloc_runtime_tests") {
testedModules.addAll("main", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "concurrent_ms_gc", "mimalloc", "mimalloc_alloc", "legacy_alloc", "objc") testedModules.addAll("main", "noop_externalCallsChecker", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "concurrent_ms_gc", "mimalloc", "mimalloc_alloc", "legacy_alloc", "objc")
} }
testsGroup("experimentalMM_cms_std_alloc_runtime_tests") { testsGroup("experimentalMM_cms_std_alloc_runtime_tests") {
testedModules.addAll("main", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "concurrent_ms_gc", "std_alloc", "legacy_alloc", "objc") testedModules.addAll("main", "noop_externalCallsChecker", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "concurrent_ms_gc", "std_alloc", "legacy_alloc", "objc")
} }
testsGroup("experimentalMM_cms_custom_alloc_runtime_tests") { testsGroup("experimentalMM_cms_custom_alloc_runtime_tests") {
testedModules.addAll("mm", "concurrent_ms_gc_custom") testedModules.addAll("mm", "concurrent_ms_gc_custom")
testSupportModules.addAll("main", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "custom_alloc", "objc") testSupportModules.addAll("main", "noop_externalCallsChecker", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "custom_alloc", "objc")
} }
testsGroup("experimentalMM_noop_mimalloc_runtime_tests") { testsGroup("experimentalMM_noop_mimalloc_runtime_tests") {
testedModules.addAll("main", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "noop_gc", "mimalloc", "mimalloc_alloc", "legacy_alloc", "objc") testedModules.addAll("main", "noop_externalCallsChecker", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "noop_gc", "mimalloc", "mimalloc_alloc", "legacy_alloc", "objc")
} }
testsGroup("experimentalMM_noop_std_alloc_runtime_tests") { testsGroup("experimentalMM_noop_std_alloc_runtime_tests") {
testedModules.addAll("main", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "noop_gc", "std_alloc", "legacy_alloc", "objc") testedModules.addAll("main", "noop_externalCallsChecker", "mm", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "noop_gc", "std_alloc", "legacy_alloc", "objc")
} }
testsGroup("experimentalMM_noop_custom_alloc_runtime_tests") { testsGroup("experimentalMM_noop_custom_alloc_runtime_tests") {
testedModules.addAll("mm", "noop_gc_custom") testedModules.addAll("mm", "noop_gc_custom")
testSupportModules.addAll("main", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "custom_alloc", "objc") testSupportModules.addAll("main", "noop_externalCallsChecker", "common_alloc", "common_gc", "common_gcScheduler", "manual_gcScheduler", "custom_alloc", "objc")
} }
testsGroup("aggressive_gcScheduler_runtime_tests") { testsGroup("aggressive_gcScheduler_runtime_tests") {
testedModules.addAll("aggressive_gcScheduler") testedModules.addAll("aggressive_gcScheduler")
testSupportModules.addAll("main", "mm", "common_alloc", "common_gc", "common_gcScheduler", "noop_gc", "std_alloc", "legacy_alloc", "objc") testSupportModules.addAll("main", "noop_externalCallsChecker", "mm", "common_alloc", "common_gc", "common_gcScheduler", "noop_gc", "std_alloc", "legacy_alloc", "objc")
} }
testsGroup("adaptive_gcScheduler_runtime_tests") { testsGroup("adaptive_gcScheduler_runtime_tests") {
testedModules.addAll("adaptive_gcScheduler") testedModules.addAll("adaptive_gcScheduler")
testSupportModules.addAll("main", "mm", "common_alloc", "common_gc", "common_gcScheduler", "noop_gc", "std_alloc", "legacy_alloc", "objc") testSupportModules.addAll("main", "noop_externalCallsChecker", "mm", "common_alloc", "common_gc", "common_gcScheduler", "noop_gc", "std_alloc", "legacy_alloc", "objc")
} }
} }
} }
@@ -8,6 +8,8 @@
#include "Common.h" #include "Common.h"
#include "Utils.hpp" #include "Utils.hpp"
#define NO_EXTERNAL_CALLS_CHECK __attribute__((annotate("no_external_calls_check")))
namespace kotlin { namespace kotlin {
// Ignore thread state checker for the scope. // Ignore thread state checker for the scope.
@@ -19,4 +21,4 @@ public:
ALWAYS_INLINE ~CallsCheckerIgnoreGuard(); ALWAYS_INLINE ~CallsCheckerIgnoreGuard();
}; };
} } // namespace kotlin
@@ -20,7 +20,7 @@
using namespace kotlin; using namespace kotlin;
// this values will be substituted by compiler // this values will be substituted by compiler
extern "C" const void **Kotlin_callsCheckerKnownFunctions = nullptr; extern "C" const void** Kotlin_callsCheckerKnownFunctions = nullptr;
extern "C" int Kotlin_callsCheckerKnownFunctionsCount = 0; extern "C" int Kotlin_callsCheckerKnownFunctionsCount = 0;
extern "C" const char* Kotlin_callsCheckerGoodFunctionNames[] = { extern "C" const char* Kotlin_callsCheckerGoodFunctionNames[] = {
@@ -290,13 +290,13 @@ public:
for (int i = 0; i < Kotlin_callsCheckerKnownFunctionsCount; i++) { for (int i = 0; i < Kotlin_callsCheckerKnownFunctionsCount; i++) {
known_functions_.insert(Kotlin_callsCheckerKnownFunctions[i]); known_functions_.insert(Kotlin_callsCheckerKnownFunctions[i]);
} }
std::copy(std::begin(Kotlin_callsCheckerGoodFunctionNames), std::end(Kotlin_callsCheckerGoodFunctionNames), std::begin(good_names_copy_)); std::copy(
std::begin(Kotlin_callsCheckerGoodFunctionNames), std::end(Kotlin_callsCheckerGoodFunctionNames),
std::begin(good_names_copy_));
std::sort(std::begin(good_names_copy_), std::end(good_names_copy_)); std::sort(std::begin(good_names_copy_), std::end(good_names_copy_));
} }
bool isKnown(const void* fun) const noexcept { bool isKnown(const void* fun) const noexcept { return known_functions_.find(fun) != known_functions_.end(); }
return known_functions_.find(fun) != known_functions_.end();
}
bool isSafeByName(std::string_view name) const noexcept { bool isSafeByName(std::string_view name) const noexcept {
auto it = std::lower_bound(std::begin(good_names_copy_), std::end(good_names_copy_), name); auto it = std::lower_bound(std::begin(good_names_copy_), std::end(good_names_copy_), name);
@@ -307,10 +307,10 @@ public:
return name.substr(0, banned.size() - 1) == banned.substr(0, banned.size() - 1); return name.substr(0, banned.size() - 1) == banned.substr(0, banned.size() - 1);
}; };
if (it != std::end(good_names_copy_) && check(*it)) { if (it != std::end(good_names_copy_) && check(*it)) {
return true; return true;
} }
if (it != std::begin(good_names_copy_) && check(*std::prev(it))) { if (it != std::begin(good_names_copy_) && check(*std::prev(it))) {
return true; return true;
} }
return false; return false;
} }
@@ -324,13 +324,12 @@ private:
[[clang::no_destroy]] const KnownFunctionChecker checker; [[clang::no_destroy]] const KnownFunctionChecker checker;
constexpr int MSG_SEND_TO_NULL = -1; constexpr int MSG_SEND_TO_NULL = -1;
constexpr int CALLED_LLVM_BUILTIN = -2; constexpr int CALLED_LLVM_BUILTIN = -2;
thread_local size_t ignoreGuardsCount = 0; thread_local size_t ignoreGuardsCount = 0;
} } // namespace
/** /**
* This function calls is inserted to llvm bitcode automatically, so it can be called almost anywhre. * This function calls is inserted to llvm bitcode automatically, so it can be called almost anywhre.
@@ -342,7 +341,8 @@ thread_local size_t ignoreGuardsCount = 0;
* should not be accessed. So before guard checking we need to check is thread destructor is running, * should not be accessed. So before guard checking we need to check is thread destructor is running,
* which requires special handling of recursive calls from this check. * which requires special handling of recursive calls from this check.
*/ */
extern "C" RUNTIME_NOTHROW RUNTIME_NODEBUG void Kotlin_mm_checkStateAtExternalFunctionCall(const char* caller, const char *callee, const void *calleePtr) noexcept { extern "C" RUNTIME_NOTHROW RUNTIME_NODEBUG void Kotlin_mm_checkStateAtExternalFunctionCall(
const char* caller, const char* callee, const void* calleePtr) noexcept {
if (reinterpret_cast<int64_t>(calleePtr) == MSG_SEND_TO_NULL) return; // objc_sendMsg called on nil, it does nothing, so it's ok if (reinterpret_cast<int64_t>(calleePtr) == MSG_SEND_TO_NULL) return; // objc_sendMsg called on nil, it does nothing, so it's ok
if (ignoreGuardsCount != 0) return; if (ignoreGuardsCount != 0) return;
if (konan::isOnThreadExitNotSetOrAlreadyStarted()) return; if (konan::isOnThreadExitNotSetOrAlreadyStarted()) return;
@@ -375,5 +375,9 @@ extern "C" RUNTIME_NOTHROW RUNTIME_NODEBUG void Kotlin_mm_checkStateAtExternalFu
RuntimeFail("Expected kNative thread state at call of function %s by function %s", callee, caller); RuntimeFail("Expected kNative thread state at call of function %s by function %s", callee, caller);
} }
CallsCheckerIgnoreGuard::CallsCheckerIgnoreGuard() noexcept { ++ignoreGuardsCount; } CallsCheckerIgnoreGuard::CallsCheckerIgnoreGuard() noexcept {
CallsCheckerIgnoreGuard::~CallsCheckerIgnoreGuard() { --ignoreGuardsCount; } ++ignoreGuardsCount;
}
CallsCheckerIgnoreGuard::~CallsCheckerIgnoreGuard() {
--ignoreGuardsCount;
}
@@ -0,0 +1,11 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
#include "CallsChecker.hpp"
using namespace kotlin;
CallsCheckerIgnoreGuard::CallsCheckerIgnoreGuard() noexcept = default;
CallsCheckerIgnoreGuard::~CallsCheckerIgnoreGuard() = default;
@@ -36,8 +36,6 @@
#endif #endif
#define NO_INLINE __attribute__((noinline)) #define NO_INLINE __attribute__((noinline))
#define NO_EXTERNAL_CALLS_CHECK __attribute__((annotate("no_external_calls_check")))
#define OPTNONE __attribute__((optnone)) #define OPTNONE __attribute__((optnone))
#define THREAD_LOCAL_VARIABLE __thread #define THREAD_LOCAL_VARIABLE __thread
@@ -21,6 +21,7 @@
#include <cinttypes> #include <cinttypes>
#include <thread> #include <thread>
#include "CallsChecker.hpp"
#include "KAssert.h" #include "KAssert.h"
#include "Memory.h" #include "Memory.h"
#include "Utils.hpp" #include "Utils.hpp"
@@ -25,6 +25,7 @@
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>
#import <Foundation/NSSet.h> #import <Foundation/NSSet.h>
#import "CallsChecker.hpp"
#import "Exceptions.h" #import "Exceptions.h"
#import "ObjCExport.h" #import "ObjCExport.h"
#import "ObjCExportCollections.h" #import "ObjCExportCollections.h"
@@ -30,6 +30,7 @@
#include <chrono> #include <chrono>
#include "CallsChecker.hpp"
#include "Common.h" #include "Common.h"
#include "CompilerConstants.hpp" #include "CompilerConstants.hpp"
#include "Porting.h" #include "Porting.h"
@@ -127,7 +127,7 @@ internal enum class OptimizationMode(private val description: String, val compil
*/ */
internal enum class ThreadStateChecker(val compilerFlag: String?) { internal enum class ThreadStateChecker(val compilerFlag: String?) {
DISABLED(null), DISABLED(null),
ENABLED("-Xcheck-state-at-external-calls"); ENABLED("-Xbinary=checkStateAtExternalCalls=true");
override fun toString() = compilerFlag?.let { "($it)" }.orEmpty() override fun toString() = compilerFlag?.let { "($it)" }.orEmpty()
} }