Add a separate aggressive GC mode
This commit is contained in:
committed by
Space
parent
1cfe1c41ef
commit
e240b8a8ee
@@ -293,6 +293,10 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
|
|||||||
GC.SAME_THREAD_MARK_AND_SWEEP
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -308,6 +308,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
|
|||||||
@Argument(value="-Xgc", valueDescription = "<gc>", description = "GC to use, 'noop' and 'stms' are currently supported. Works only with -memory-model experimental")
|
@Argument(value="-Xgc", valueDescription = "<gc>", description = "GC to use, 'noop' and 'stms' are currently supported. Works only with -memory-model experimental")
|
||||||
var gc: String? = null
|
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<AnalysisFlag<*>, Any> =
|
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> =
|
||||||
super.configureAnalysisFlags(collector).also {
|
super.configureAnalysisFlags(collector).also {
|
||||||
val useExperimental = it[AnalysisFlags.useExperimental] as List<*>
|
val useExperimental = it[AnalysisFlags.useExperimental] as List<*>
|
||||||
|
|||||||
+1
@@ -48,6 +48,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
val memoryModel: MemoryModel get() = configuration.get(KonanConfigKeys.MEMORY_MODEL)!!
|
val memoryModel: MemoryModel get() = configuration.get(KonanConfigKeys.MEMORY_MODEL)!!
|
||||||
val destroyRuntimeMode: DestroyRuntimeMode get() = configuration.get(KonanConfigKeys.DESTROY_RUNTIME_MODE)!!
|
val destroyRuntimeMode: DestroyRuntimeMode get() = configuration.get(KonanConfigKeys.DESTROY_RUNTIME_MODE)!!
|
||||||
val gc: GC get() = configuration.get(KonanConfigKeys.GARBAGE_COLLECTOR)!!
|
val gc: GC get() = configuration.get(KonanConfigKeys.GARBAGE_COLLECTOR)!!
|
||||||
|
val gcAggressive: Boolean get() = configuration.get(KonanConfigKeys.GARBAGE_COLLECTOR_AGRESSIVE)!!
|
||||||
|
|
||||||
val needVerifyIr: Boolean
|
val needVerifyIr: Boolean
|
||||||
get() = configuration.get(KonanConfigKeys.VERIFY_IR) == true
|
get() = configuration.get(KonanConfigKeys.VERIFY_IR) == true
|
||||||
|
|||||||
+1
@@ -155,6 +155,7 @@ class KonanConfigKeys {
|
|||||||
val DESTROY_RUNTIME_MODE: CompilerConfigurationKey<DestroyRuntimeMode>
|
val DESTROY_RUNTIME_MODE: CompilerConfigurationKey<DestroyRuntimeMode>
|
||||||
= CompilerConfigurationKey.create("when to destroy runtime")
|
= CompilerConfigurationKey.create("when to destroy runtime")
|
||||||
val GARBAGE_COLLECTOR: CompilerConfigurationKey<GC> = CompilerConfigurationKey.create("gc")
|
val GARBAGE_COLLECTOR: CompilerConfigurationKey<GC> = CompilerConfigurationKey.create("gc")
|
||||||
|
val GARBAGE_COLLECTOR_AGRESSIVE: CompilerConfigurationKey<Boolean> = CompilerConfigurationKey.create("turn on agressive GC mode")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
@@ -2458,6 +2458,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
return
|
return
|
||||||
|
|
||||||
overrideRuntimeGlobal("Kotlin_destroyRuntimeMode", Int32(context.config.destroyRuntimeMode.value))
|
overrideRuntimeGlobal("Kotlin_destroyRuntimeMode", Int32(context.config.destroyRuntimeMode.value))
|
||||||
|
overrideRuntimeGlobal("Kotlin_gcAggressive", Int32(if (context.config.gcAggressive) 1 else 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|||||||
@@ -109,6 +109,13 @@ tasks.withType(RunExternalTestGroup.class).configureEach {
|
|||||||
|
|
||||||
ext.isExperimentalMM = project.globalTestArgs.contains("-memory-model") && project.globalTestArgs.contains("experimental")
|
ext.isExperimentalMM = project.globalTestArgs.contains("-memory-model") && project.globalTestArgs.contains("experimental")
|
||||||
|
|
||||||
|
if (ext.isExperimentalMM) {
|
||||||
|
// TODO: Make it more aggressive and only turn it on for a subset of tests.
|
||||||
|
tasks.withType(KonanCompileNativeBinary.class).configureEach {
|
||||||
|
extraOpts "-Xgc-aggressive"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
// Root directories for test output (logs, compiled files, statistics etc). Only single path must be in each set.
|
// Root directories for test output (logs, compiled files, statistics etc). Only single path must be in each set.
|
||||||
// backend.native/tests
|
// backend.native/tests
|
||||||
@@ -5029,6 +5036,7 @@ if (UtilsKt.getTestTargetSupportsCodeCoverage(project)) {
|
|||||||
baseDir "$testOutputCoverage/$binaryName"
|
baseDir "$testOutputCoverage/$binaryName"
|
||||||
entryPoint "coverage.basic.program.main"
|
entryPoint "coverage.basic.program.main"
|
||||||
extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile"
|
extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile"
|
||||||
|
extraOpts project.globalTestArgs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5051,6 +5059,7 @@ if (UtilsKt.getTestTargetSupportsCodeCoverage(project)) {
|
|||||||
baseDir "$testOutputCoverage/$binaryName"
|
baseDir "$testOutputCoverage/$binaryName"
|
||||||
entryPoint "coverage.basic.library.main"
|
entryPoint "coverage.basic.library.main"
|
||||||
extraOpts "-Xcoverage-file=$profrawFile", "-Xlibrary-to-cover=${konanArtifacts.lib_to_cover.getArtifactByTarget(target.name)}"
|
extraOpts "-Xcoverage-file=$profrawFile", "-Xlibrary-to-cover=${konanArtifacts.lib_to_cover.getArtifactByTarget(target.name)}"
|
||||||
|
extraOpts project.globalTestArgs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5066,6 +5075,7 @@ if (UtilsKt.getTestTargetSupportsCodeCoverage(project)) {
|
|||||||
baseDir "$testOutputCoverage/$binaryName"
|
baseDir "$testOutputCoverage/$binaryName"
|
||||||
entryPoint "coverage.basic.controlflow.main"
|
entryPoint "coverage.basic.controlflow.main"
|
||||||
extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile"
|
extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile"
|
||||||
|
extraOpts project.globalTestArgs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5081,6 +5091,7 @@ if (UtilsKt.getTestTargetSupportsCodeCoverage(project)) {
|
|||||||
baseDir "$testOutputCoverage/$binaryName"
|
baseDir "$testOutputCoverage/$binaryName"
|
||||||
entryPoint "coverage.basic.jumps.main"
|
entryPoint "coverage.basic.jumps.main"
|
||||||
extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile"
|
extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile"
|
||||||
|
extraOpts project.globalTestArgs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5096,6 +5107,7 @@ if (UtilsKt.getTestTargetSupportsCodeCoverage(project)) {
|
|||||||
baseDir "$testOutputCoverage/$binaryName"
|
baseDir "$testOutputCoverage/$binaryName"
|
||||||
entryPoint "coverage.basic.smoke0.main"
|
entryPoint "coverage.basic.smoke0.main"
|
||||||
extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile"
|
extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile"
|
||||||
|
extraOpts project.globalTestArgs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5111,6 +5123,7 @@ if (UtilsKt.getTestTargetSupportsCodeCoverage(project)) {
|
|||||||
baseDir "$testOutputCoverage/$binaryName"
|
baseDir "$testOutputCoverage/$binaryName"
|
||||||
entryPoint "coverage.basic.smoke1.main"
|
entryPoint "coverage.basic.smoke1.main"
|
||||||
extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile"
|
extraOpts "-Xcoverage", "-Xcoverage-file=$profrawFile"
|
||||||
|
extraOpts project.globalTestArgs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,14 @@ void gc::SameThreadMarkAndSweep::ThreadData::SafePointRegular(size_t weight) noe
|
|||||||
safePointsCounter_ += weight;
|
safePointsCounter_ += weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gc::SameThreadMarkAndSweep::SameThreadMarkAndSweep() noexcept {
|
||||||
|
if (Kotlin_getGcAggressive()) {
|
||||||
|
// TODO: Make it even more aggressive and run on a subset of backend.native tests.
|
||||||
|
threshold_ = 1000;
|
||||||
|
allocationThresholdBytes_ = 10000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mm::ObjectFactory<gc::SameThreadMarkAndSweep>::FinalizerQueue gc::SameThreadMarkAndSweep::PerformFullGC() noexcept {
|
mm::ObjectFactory<gc::SameThreadMarkAndSweep>::FinalizerQueue gc::SameThreadMarkAndSweep::PerformFullGC() noexcept {
|
||||||
bool didSuspend = mm::SuspendThreads();
|
bool didSuspend = mm::SuspendThreads();
|
||||||
if (!didSuspend) {
|
if (!didSuspend) {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public:
|
|||||||
size_t safePointsCounter_ = 0;
|
size_t safePointsCounter_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
SameThreadMarkAndSweep() noexcept {}
|
SameThreadMarkAndSweep() noexcept;
|
||||||
~SameThreadMarkAndSweep() = default;
|
~SameThreadMarkAndSweep() = default;
|
||||||
|
|
||||||
void SetThreshold(size_t value) noexcept { threshold_ = value; }
|
void SetThreshold(size_t value) noexcept { threshold_ = value; }
|
||||||
@@ -78,8 +78,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
mm::ObjectFactory<SameThreadMarkAndSweep>::FinalizerQueue PerformFullGC() noexcept;
|
mm::ObjectFactory<SameThreadMarkAndSweep>::FinalizerQueue PerformFullGC() noexcept;
|
||||||
|
|
||||||
size_t threshold_ = 1000;
|
size_t threshold_ = 100000; // Roughly 1 safepoint per 10ms (on a subset of examples on one particular machine).
|
||||||
size_t allocationThresholdBytes_ = 10000;
|
size_t allocationThresholdBytes_ = 10 * 1024 * 1024; // 10MiB by default.
|
||||||
bool autoTune_ = false;
|
bool autoTune_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -31,13 +31,18 @@ struct InitNode {
|
|||||||
InitNode* next;
|
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 DestroyRuntimeMode Kotlin_destroyRuntimeMode = DESTROY_RUNTIME_ON_SHUTDOWN;
|
||||||
|
RUNTIME_WEAK KInt Kotlin_gcAggressive = 0;
|
||||||
|
|
||||||
DestroyRuntimeMode Kotlin_getDestroyRuntimeMode() {
|
DestroyRuntimeMode Kotlin_getDestroyRuntimeMode() {
|
||||||
return Kotlin_destroyRuntimeMode;
|
return Kotlin_destroyRuntimeMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Kotlin_getGcAggressive() {
|
||||||
|
return Kotlin_gcAggressive != 0;
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
InitNode* initHeadNode = nullptr;
|
InitNode* initHeadNode = nullptr;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ enum DestroyRuntimeMode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DestroyRuntimeMode Kotlin_getDestroyRuntimeMode();
|
DestroyRuntimeMode Kotlin_getDestroyRuntimeMode();
|
||||||
|
bool Kotlin_getGcAggressive();
|
||||||
|
|
||||||
// For experimental MM, if runtime gets initialized, it will be in the native state after this.
|
// For experimental MM, if runtime gets initialized, it will be in the native state after this.
|
||||||
RUNTIME_NOTHROW void Kotlin_initRuntimeIfNeeded();
|
RUNTIME_NOTHROW void Kotlin_initRuntimeIfNeeded();
|
||||||
|
|||||||
Reference in New Issue
Block a user