From 08f85c27bb545319fd7f2ad0618702271a802c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 8 May 2023 11:32:47 +0200 Subject: Darwin: Use direct runtime interface to manage autorelease pools MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Objective-C runtime supports autorelease pools via a language specific ABI supplement, akin to the “Itanium” generic ABI for C++. https://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime-support These interfaces are used by NSAutoreleasePool internally, as well as inserted by the compiler when using the @autoreleasepool syntax in Objective-C code. We have our own wrapper, QMacAutoReleasePool, which allows us to set up pools in C++ code as well. We now use these lower level interfaces in the implementation, instead of NSAutoreleasePool, as this reduces overhead due to not needing to allocate and destroy a NSAutoreleasePool. This also opens up the possibility of using Automatic Reference Counting (ARC) in Qt down the road, as explicit NSAutoreleasePool usage is forbidden in that mode (while @autoreleasepool is not, and uses the runtime ABI internally as before). Change-Id: I06fdb4a24ae4972820f866e0a129a1b355bc8a6b Reviewed-by: Timur Pocheptsov --- src/corelib/kernel/qcore_mac.mm | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/corelib/kernel/qcore_mac.mm b/src/corelib/kernel/qcore_mac.mm index d3bb2e7c4f..2ad835b754 100644 --- a/src/corelib/kernel/qcore_mac.mm +++ b/src/corelib/kernel/qcore_mac.mm @@ -224,10 +224,20 @@ QT_USE_NAMESPACE QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAutoReleasePoolTracker); #endif // QT_DEBUG +// Use the direct runtime interface to manage autorelease pools, as it +// has less overhead then allocating NSAutoreleasePools, and allows for +// a future where we use ARC (where NSAutoreleasePool is not allowed). +// https://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime-support + +extern "C" { +void *objc_autoreleasePoolPush(void); +void objc_autoreleasePoolPop(void *pool); +} + QT_BEGIN_NAMESPACE QMacAutoReleasePool::QMacAutoReleasePool() - : pool([[NSAutoreleasePool alloc] init]) + : pool(objc_autoreleasePoolPush()) { #ifdef QT_DEBUG static const bool debugAutoReleasePools = qEnvironmentVariableIsSet("QT_DARWIN_DEBUG_AUTORELEASEPOOLS"); @@ -272,10 +282,7 @@ QMacAutoReleasePool::QMacAutoReleasePool() QMacAutoReleasePool::~QMacAutoReleasePool() { - // Drain behaves the same as release, with the advantage that - // if we're ever used in a garbage-collected environment, the - // drain acts as a hint to the garbage collector to collect. - [static_cast(pool) drain]; + objc_autoreleasePoolPop(pool); } #ifndef QT_NO_DEBUG_STREAM -- cgit v1.2.1