From e178567bbb75fe798377b39986877808070dc51a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 9 Feb 2025 12:38:51 -0800 Subject: [PATCH] QCoreApplication: avoid extra work in applicationFilePath() if we can In the four OSes where qAppFileName() returns non-empty, the returned path is always absolute and canonical, so there's no need for us to further canonicalize it. So let's have applicationDirPath() have an early out for it and mark it as Q_LIKELY(). In the other OSes, qAppFileName() is static inline in this very file, so the compiler will probably see that it's always empty and ignore the Q_LIKELY(). That leaves the atypical cases of /proc/self/exe being empty on Linux (I don't know when this could happen, but it's not impossible) or non- bundle executables on Apple OSes. Change-Id: Ic47b28bda60085bcbcc8fffd28a0f3b864e07fd5 Reviewed-by: Ahmad Samir --- src/corelib/kernel/qcoreapplication.cpp | 5 +++++ src/corelib/kernel/qcoreapplication_mac.cpp | 1 + src/corelib/kernel/qcoreapplication_win.cpp | 6 +++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index f3934210797..09b7c4fce31 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -2449,6 +2449,11 @@ QString QCoreApplication::applicationFilePath() return d->cachedApplicationFilePath; QString absPath = qAppFileName(); + if (Q_LIKELY(!absPath.isEmpty())) { // Darwin, FreeBSD, Linux, Windows + // the OS has canonicalized for us + return d->cachedApplicationFilePath = std::move(absPath); + } + if (absPath.isEmpty() && !arguments().isEmpty()) { QString argv0 = QFile::decodeName(arguments().at(0).toLocal8Bit()); diff --git a/src/corelib/kernel/qcoreapplication_mac.cpp b/src/corelib/kernel/qcoreapplication_mac.cpp index af047fe8cde..982672caa57 100644 --- a/src/corelib/kernel/qcoreapplication_mac.cpp +++ b/src/corelib/kernel/qcoreapplication_mac.cpp @@ -12,6 +12,7 @@ QT_BEGIN_NAMESPACE *****************************************************************************/ QString qAppFileName() { + // QCoreApplication::applicationFilePath() expects a canonical path static QString appFileName; if (appFileName.isEmpty()) { QCFType bundleURL(CFBundleCopyExecutableURL(CFBundleGetMainBundle())); diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 9011e3fe9e6..2cdf0d57d46 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -5,6 +5,7 @@ #include "qcoreapplication.h" #include "qcoreapplication_p.h" #include "qstringlist.h" +#include "qdir.h" #include "qfileinfo.h" #ifndef QT_NO_QOBJECT #include "qmutex.h" @@ -52,7 +53,10 @@ QString qAppFileName() // get application file name v = GetModuleFileName(hInstance, space.data(), DWORD(space.size())); } while (Q_UNLIKELY(v >= size)); - return QString::fromWCharArray(space.data(), v); + // QCoreApplication::applicationFilePath() expects a canonical path with + // Qt-style separators + QStringView nativePath(space.data(), v); + return QDir::fromNativeSeparators(nativePath.toString()); } QString QCoreApplicationPrivate::appName() const