diff --git a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt index 1ccd72136a4..d38e008c29b 100644 --- a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt +++ b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt @@ -293,6 +293,10 @@ class K2Native : CLICompiler() { GC.SAME_THREAD_MARK_AND_SWEEP } }) + if (memoryModel != MemoryModel.EXPERIMENTAL && arguments.gcAggressive) { + configuration.report(ERROR, "-Xgc-aggressive is only supported for -memory-model experimental") + } + put(GARBAGE_COLLECTOR_AGRESSIVE, arguments.gcAggressive) } } } diff --git a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt index c6efd07375c..837db15b20e 100644 --- a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt +++ b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt @@ -308,6 +308,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() { @Argument(value="-Xgc", valueDescription = "", description = "GC to use, 'noop' and 'stms' are currently supported. Works only with -memory-model experimental") var gc: String? = null + @Argument(value="-Xgc-aggressive", description = "Make GC agressive. Works only with -memory-model experimental") + var gcAggressive: Boolean = false + override fun configureAnalysisFlags(collector: MessageCollector): MutableMap, Any> = super.configureAnalysisFlags(collector).also { val useExperimental = it[AnalysisFlags.useExperimental] as List<*> diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt index 71eb03e81be..fffa46d3abb 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt @@ -48,6 +48,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration val memoryModel: MemoryModel get() = configuration.get(KonanConfigKeys.MEMORY_MODEL)!! val destroyRuntimeMode: DestroyRuntimeMode get() = configuration.get(KonanConfigKeys.DESTROY_RUNTIME_MODE)!! val gc: GC get() = configuration.get(KonanConfigKeys.GARBAGE_COLLECTOR)!! + val gcAggressive: Boolean get() = configuration.get(KonanConfigKeys.GARBAGE_COLLECTOR_AGRESSIVE)!! val needVerifyIr: Boolean get() = configuration.get(KonanConfigKeys.VERIFY_IR) == true diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt index 97dad2a452a..cce2ba97021 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt @@ -155,6 +155,7 @@ class KonanConfigKeys { val DESTROY_RUNTIME_MODE: CompilerConfigurationKey = CompilerConfigurationKey.create("when to destroy runtime") val GARBAGE_COLLECTOR: CompilerConfigurationKey = CompilerConfigurationKey.create("gc") + val GARBAGE_COLLECTOR_AGRESSIVE: CompilerConfigurationKey = CompilerConfigurationKey.create("turn on agressive GC mode") } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 0fd6b64da18..b7317b277b3 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -2458,6 +2458,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map::FinalizerQueue gc::SameThreadMarkAndSweep::PerformFullGC() noexcept { bool didSuspend = mm::SuspendThreads(); if (!didSuspend) { diff --git a/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.hpp b/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.hpp index b55a7222a88..92163082779 100644 --- a/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.hpp +++ b/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.hpp @@ -63,7 +63,7 @@ public: size_t safePointsCounter_ = 0; }; - SameThreadMarkAndSweep() noexcept {} + SameThreadMarkAndSweep() noexcept; ~SameThreadMarkAndSweep() = default; void SetThreshold(size_t value) noexcept { threshold_ = value; } @@ -78,8 +78,8 @@ public: private: mm::ObjectFactory::FinalizerQueue PerformFullGC() noexcept; - size_t threshold_ = 1000; - size_t allocationThresholdBytes_ = 10000; + size_t threshold_ = 100000; // Roughly 1 safepoint per 10ms (on a subset of examples on one particular machine). + size_t allocationThresholdBytes_ = 10 * 1024 * 1024; // 10MiB by default. bool autoTune_ = false; }; diff --git a/kotlin-native/runtime/src/main/cpp/Runtime.cpp b/kotlin-native/runtime/src/main/cpp/Runtime.cpp index db29716c3b0..4bd0784ea2d 100644 --- a/kotlin-native/runtime/src/main/cpp/Runtime.cpp +++ b/kotlin-native/runtime/src/main/cpp/Runtime.cpp @@ -31,13 +31,18 @@ struct InitNode { InitNode* next; }; -// This global is overriden by the compiler. +// These globals are overriden by the compiler. RUNTIME_WEAK DestroyRuntimeMode Kotlin_destroyRuntimeMode = DESTROY_RUNTIME_ON_SHUTDOWN; +RUNTIME_WEAK KInt Kotlin_gcAggressive = 0; DestroyRuntimeMode Kotlin_getDestroyRuntimeMode() { return Kotlin_destroyRuntimeMode; } +bool Kotlin_getGcAggressive() { + return Kotlin_gcAggressive != 0; +} + namespace { InitNode* initHeadNode = nullptr; diff --git a/kotlin-native/runtime/src/main/cpp/Runtime.h b/kotlin-native/runtime/src/main/cpp/Runtime.h index 001fb15e593..8e831973af4 100644 --- a/kotlin-native/runtime/src/main/cpp/Runtime.h +++ b/kotlin-native/runtime/src/main/cpp/Runtime.h @@ -32,6 +32,7 @@ enum DestroyRuntimeMode { }; DestroyRuntimeMode Kotlin_getDestroyRuntimeMode(); +bool Kotlin_getGcAggressive(); // For experimental MM, if runtime gets initialized, it will be in the native state after this. RUNTIME_NOTHROW void Kotlin_initRuntimeIfNeeded();