[K/N] Put FinalizerProcessor CFRunLoop usage under a flag ^KT-64313
This commit is contained in:
committed by
Space Team
parent
8ff869a08c
commit
5208b3c024
+2
@@ -65,6 +65,8 @@ object BinaryOptions : BinaryOptionRegistry() {
|
|||||||
|
|
||||||
val objcDisposeOnMain by booleanOption()
|
val objcDisposeOnMain by booleanOption()
|
||||||
|
|
||||||
|
val objcDisposeWithRunLoop by booleanOption()
|
||||||
|
|
||||||
val disableMmap by booleanOption()
|
val disableMmap by booleanOption()
|
||||||
|
|
||||||
val disableAllocatorOverheadEstimate by booleanOption()
|
val disableAllocatorOverheadEstimate by booleanOption()
|
||||||
|
|||||||
+4
@@ -245,6 +245,10 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
|||||||
configuration.get(BinaryOptions.objcDisposeOnMain) ?: true
|
configuration.get(BinaryOptions.objcDisposeOnMain) ?: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val objcDisposeWithRunLoop: Boolean by lazy {
|
||||||
|
configuration.get(BinaryOptions.objcDisposeWithRunLoop) ?: true
|
||||||
|
}
|
||||||
|
|
||||||
val enableSafepointSignposts: Boolean = configuration.get(BinaryOptions.enableSafepointSignposts)?.also {
|
val enableSafepointSignposts: Boolean = configuration.get(BinaryOptions.enableSafepointSignposts)?.also {
|
||||||
if (it && !target.supportsSignposts) {
|
if (it && !target.supportsSignposts) {
|
||||||
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "Signposts are not available on $target. The setting will have no effect.")
|
configuration.report(CompilerMessageSeverity.STRONG_WARNING, "Signposts are not available on $target. The setting will have no effect.")
|
||||||
|
|||||||
+1
@@ -2817,6 +2817,7 @@ internal class CodeGeneratorVisitor(
|
|||||||
overrideRuntimeGlobal("Kotlin_mimallocUseDefaultOptions", llvm.constInt32(if (context.config.mimallocUseDefaultOptions) 1 else 0))
|
overrideRuntimeGlobal("Kotlin_mimallocUseDefaultOptions", llvm.constInt32(if (context.config.mimallocUseDefaultOptions) 1 else 0))
|
||||||
overrideRuntimeGlobal("Kotlin_mimallocUseCompaction", llvm.constInt32(if (context.config.mimallocUseCompaction) 1 else 0))
|
overrideRuntimeGlobal("Kotlin_mimallocUseCompaction", llvm.constInt32(if (context.config.mimallocUseCompaction) 1 else 0))
|
||||||
overrideRuntimeGlobal("Kotlin_objcDisposeOnMain", llvm.constInt32(if (context.config.objcDisposeOnMain) 1 else 0))
|
overrideRuntimeGlobal("Kotlin_objcDisposeOnMain", llvm.constInt32(if (context.config.objcDisposeOnMain) 1 else 0))
|
||||||
|
overrideRuntimeGlobal("Kotlin_objcDisposeWithRunLoop", llvm.constInt32(if (context.config.objcDisposeWithRunLoop) 1 else 0))
|
||||||
overrideRuntimeGlobal("Kotlin_enableSafepointSignposts", llvm.constInt32(if (context.config.enableSafepointSignposts) 1 else 0))
|
overrideRuntimeGlobal("Kotlin_enableSafepointSignposts", llvm.constInt32(if (context.config.enableSafepointSignposts) 1 else 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public:
|
|||||||
// epochDoneCallback could be called on any subset of them.
|
// epochDoneCallback could be called on any subset of them.
|
||||||
// If no new tasks are set, epochDoneCallback will be eventually called on last epoch
|
// If no new tasks are set, epochDoneCallback will be eventually called on last epoch
|
||||||
explicit FinalizerProcessor(std::function<void(int64_t)> epochDoneCallback) noexcept :
|
explicit FinalizerProcessor(std::function<void(int64_t)> epochDoneCallback) noexcept :
|
||||||
epochDoneCallback_(std::move(epochDoneCallback)), processingLoop_(*this) {}
|
epochDoneCallback_(std::move(epochDoneCallback)), processingLoop_(makeProcessingLoop(*this)) {}
|
||||||
|
|
||||||
~FinalizerProcessor() { StopFinalizerThread(); }
|
~FinalizerProcessor() { StopFinalizerThread(); }
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ public:
|
|||||||
StartFinalizerThreadIfNone();
|
StartFinalizerThreadIfNone();
|
||||||
FinalizerQueueTraits::add(finalizerQueue_, std::move(tasks));
|
FinalizerQueueTraits::add(finalizerQueue_, std::move(tasks));
|
||||||
finalizerQueueEpoch_ = epoch;
|
finalizerQueueEpoch_ = epoch;
|
||||||
processingLoop_.notify();
|
processingLoop_->notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopFinalizerThread() noexcept {
|
void StopFinalizerThread() noexcept {
|
||||||
@@ -54,7 +54,7 @@ public:
|
|||||||
std::unique_lock guard(finalizerQueueMutex_);
|
std::unique_lock guard(finalizerQueueMutex_);
|
||||||
if (!finalizerThread_.joinable()) return;
|
if (!finalizerThread_.joinable()) return;
|
||||||
shutdownFlag_ = true;
|
shutdownFlag_ = true;
|
||||||
processingLoop_.notify();
|
processingLoop_->notify();
|
||||||
}
|
}
|
||||||
finalizerThread_.join();
|
finalizerThread_.join();
|
||||||
shutdownFlag_ = false;
|
shutdownFlag_ = false;
|
||||||
@@ -71,14 +71,14 @@ public:
|
|||||||
if (finalizerThread_.joinable()) return;
|
if (finalizerThread_.joinable()) return;
|
||||||
|
|
||||||
finalizerThread_ = ScopedThread(ScopedThread::attributes().name("GC finalizer processor"), [this] {
|
finalizerThread_ = ScopedThread(ScopedThread::attributes().name("GC finalizer processor"), [this] {
|
||||||
processingLoop_.initThreadData();
|
processingLoop_->initThreadData();
|
||||||
Kotlin_initRuntimeIfNeeded();
|
Kotlin_initRuntimeIfNeeded();
|
||||||
{
|
{
|
||||||
std::unique_lock guard(initializedMutex_);
|
std::unique_lock guard(initializedMutex_);
|
||||||
initialized_ = true;
|
initialized_ = true;
|
||||||
}
|
}
|
||||||
initializedCondVar_.notify_all();
|
initializedCondVar_.notify_all();
|
||||||
processingLoop_.body();
|
processingLoop_->body();
|
||||||
{
|
{
|
||||||
std::unique_lock guard(initializedMutex_);
|
std::unique_lock guard(initializedMutex_);
|
||||||
initialized_ = false;
|
initialized_ = false;
|
||||||
@@ -109,24 +109,33 @@ private:
|
|||||||
epochDoneCallback_(currentEpoch);
|
epochDoneCallback_(currentEpoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if KONAN_OBJC_INTEROP
|
class ProcessingLoop : private Pinned {
|
||||||
class ProcessingLoop {
|
|
||||||
public:
|
public:
|
||||||
explicit ProcessingLoop(FinalizerProcessor& owner) :
|
virtual ~ProcessingLoop() = default;
|
||||||
|
|
||||||
|
virtual void notify() = 0;
|
||||||
|
virtual void initThreadData() = 0;
|
||||||
|
virtual void body() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if KONAN_OBJC_INTEROP
|
||||||
|
class ProcessingLoopWithCFImpl final : public ProcessingLoop {
|
||||||
|
public:
|
||||||
|
explicit ProcessingLoopWithCFImpl(FinalizerProcessor& owner) :
|
||||||
owner_(owner),
|
owner_(owner),
|
||||||
sourceContext_{
|
sourceContext_{
|
||||||
0, this, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
0, this, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||||
[](void* info) {
|
[](void* info) {
|
||||||
auto& self = *reinterpret_cast<ProcessingLoop*>(info);
|
auto& self = *static_cast<ProcessingLoopWithCFImpl*>(info);
|
||||||
self.handleNewFinalizers();
|
self.handleNewFinalizers();
|
||||||
}},
|
}},
|
||||||
runLoopSource_(CFRunLoopSourceCreate(nullptr, 0, &sourceContext_)) {}
|
runLoopSource_(CFRunLoopSourceCreate(nullptr, 0, &sourceContext_)) {}
|
||||||
|
|
||||||
~ProcessingLoop() {
|
~ProcessingLoopWithCFImpl() override {
|
||||||
CFRelease(runLoopSource_);
|
CFRelease(runLoopSource_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void notify() {
|
void notify() override {
|
||||||
// wait until runLoop_ ptr is published
|
// wait until runLoop_ ptr is published
|
||||||
while (runLoop_.load(std::memory_order_acquire) == nullptr) {
|
while (runLoop_.load(std::memory_order_acquire) == nullptr) {
|
||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
@@ -136,11 +145,11 @@ private:
|
|||||||
CFRunLoopWakeUp(runLoop_);
|
CFRunLoopWakeUp(runLoop_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initThreadData() {
|
void initThreadData() override {
|
||||||
runLoop_.store(CFRunLoopGetCurrent(), std::memory_order_release);
|
runLoop_.store(CFRunLoopGetCurrent(), std::memory_order_release);
|
||||||
}
|
}
|
||||||
|
|
||||||
void body() {
|
void body() override {
|
||||||
konan::AutoreleasePool autoreleasePool;
|
konan::AutoreleasePool autoreleasePool;
|
||||||
auto mode = kCFRunLoopDefaultMode;
|
auto mode = kCFRunLoopDefaultMode;
|
||||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource_, mode);
|
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource_, mode);
|
||||||
@@ -150,6 +159,7 @@ private:
|
|||||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoopSource_, mode);
|
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoopSource_, mode);
|
||||||
runLoop_.store(nullptr, std::memory_order_release);
|
runLoop_.store(nullptr, std::memory_order_release);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleNewFinalizers() {
|
void handleNewFinalizers() {
|
||||||
std::unique_lock lock(owner_.finalizerQueueMutex_);
|
std::unique_lock lock(owner_.finalizerQueueMutex_);
|
||||||
@@ -172,18 +182,19 @@ private:
|
|||||||
std::atomic<CFRunLoopRef> runLoop_ = nullptr;
|
std::atomic<CFRunLoopRef> runLoop_ = nullptr;
|
||||||
CFRunLoopSourceRef runLoopSource_;
|
CFRunLoopSourceRef runLoopSource_;
|
||||||
};
|
};
|
||||||
#else
|
#endif
|
||||||
class ProcessingLoop {
|
|
||||||
public:
|
|
||||||
explicit ProcessingLoop(FinalizerProcessor& owner) : owner_(owner) {}
|
|
||||||
|
|
||||||
void notify() {
|
class ProcessingLoopImpl final : public ProcessingLoop {
|
||||||
|
public:
|
||||||
|
explicit ProcessingLoopImpl(FinalizerProcessor& owner) : owner_(owner) {}
|
||||||
|
|
||||||
|
void notify() override {
|
||||||
owner_.finalizerQueueCondVar_.notify_all();
|
owner_.finalizerQueueCondVar_.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initThreadData() { /* noop */ }
|
void initThreadData() override { /* noop */ }
|
||||||
|
|
||||||
void body() {
|
void body() override {
|
||||||
int64_t finishedEpoch = 0;
|
int64_t finishedEpoch = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
std::unique_lock lock(owner_.finalizerQueueMutex_);
|
std::unique_lock lock(owner_.finalizerQueueMutex_);
|
||||||
@@ -202,10 +213,19 @@ private:
|
|||||||
finishedEpoch = currentEpoch;
|
finishedEpoch = currentEpoch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FinalizerProcessor& owner_;
|
FinalizerProcessor& owner_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static std::unique_ptr<ProcessingLoop> makeProcessingLoop(FinalizerProcessor& owner) noexcept {
|
||||||
|
#if KONAN_OBJC_INTEROP
|
||||||
|
if (compiler::objcDisposeWithRunLoop()) {
|
||||||
|
return std::make_unique<ProcessingLoopWithCFImpl>(owner);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return std::make_unique<ProcessingLoopImpl>(owner);
|
||||||
|
}
|
||||||
|
|
||||||
ScopedThread finalizerThread_;
|
ScopedThread finalizerThread_;
|
||||||
FinalizerQueue finalizerQueue_;
|
FinalizerQueue finalizerQueue_;
|
||||||
@@ -216,7 +236,7 @@ private:
|
|||||||
bool shutdownFlag_ = false;
|
bool shutdownFlag_ = false;
|
||||||
bool newTasksAllowed_ = true;
|
bool newTasksAllowed_ = true;
|
||||||
|
|
||||||
ProcessingLoop processingLoop_;
|
std::unique_ptr<ProcessingLoop> processingLoop_;
|
||||||
|
|
||||||
std::mutex initializedMutex_;
|
std::mutex initializedMutex_;
|
||||||
std::condition_variable initializedCondVar_;
|
std::condition_variable initializedCondVar_;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ RUNTIME_WEAK int32_t Kotlin_appStateTracking = 0;
|
|||||||
RUNTIME_WEAK int32_t Kotlin_mimallocUseDefaultOptions = 1;
|
RUNTIME_WEAK int32_t Kotlin_mimallocUseDefaultOptions = 1;
|
||||||
RUNTIME_WEAK int32_t Kotlin_mimallocUseCompaction = 0;
|
RUNTIME_WEAK int32_t Kotlin_mimallocUseCompaction = 0;
|
||||||
RUNTIME_WEAK int32_t Kotlin_objcDisposeOnMain = 0;
|
RUNTIME_WEAK int32_t Kotlin_objcDisposeOnMain = 0;
|
||||||
|
RUNTIME_WEAK int32_t Kotlin_objcDisposeWithRunLoop = 1;
|
||||||
RUNTIME_WEAK int32_t Kotlin_enableSafepointSignposts = 0;
|
RUNTIME_WEAK int32_t Kotlin_enableSafepointSignposts = 0;
|
||||||
|
|
||||||
ALWAYS_INLINE compiler::DestroyRuntimeMode compiler::destroyRuntimeMode() noexcept {
|
ALWAYS_INLINE compiler::DestroyRuntimeMode compiler::destroyRuntimeMode() noexcept {
|
||||||
@@ -85,6 +86,10 @@ ALWAYS_INLINE bool compiler::objcDisposeOnMain() noexcept {
|
|||||||
return Kotlin_objcDisposeOnMain != 0;
|
return Kotlin_objcDisposeOnMain != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE bool compiler::objcDisposeWithRunLoop() noexcept {
|
||||||
|
return Kotlin_objcDisposeWithRunLoop != 0;
|
||||||
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE bool compiler::enableSafepointSignposts() noexcept {
|
ALWAYS_INLINE bool compiler::enableSafepointSignposts() noexcept {
|
||||||
return Kotlin_enableSafepointSignposts != 0;
|
return Kotlin_enableSafepointSignposts != 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ int getSourceInfo(void* addr, SourceInfo *result, int result_size) noexcept;
|
|||||||
bool mimallocUseDefaultOptions() noexcept;
|
bool mimallocUseDefaultOptions() noexcept;
|
||||||
bool mimallocUseCompaction() noexcept;
|
bool mimallocUseCompaction() noexcept;
|
||||||
bool objcDisposeOnMain() noexcept;
|
bool objcDisposeOnMain() noexcept;
|
||||||
|
bool objcDisposeWithRunLoop() noexcept;
|
||||||
bool enableSafepointSignposts() noexcept;
|
bool enableSafepointSignposts() noexcept;
|
||||||
|
|
||||||
#ifdef KONAN_ANDROID
|
#ifdef KONAN_ANDROID
|
||||||
|
|||||||
Reference in New Issue
Block a user