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 <a.samirh78@gmail.com>
This commit is contained in:
Thiago Macieira 2025-02-09 12:38:51 -08:00
parent d34a3536bf
commit e178567bbb
3 changed files with 11 additions and 1 deletions

View File

@ -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());

View File

@ -12,6 +12,7 @@ QT_BEGIN_NAMESPACE
*****************************************************************************/
QString qAppFileName()
{
// QCoreApplication::applicationFilePath() expects a canonical path
static QString appFileName;
if (appFileName.isEmpty()) {
QCFType<CFURLRef> bundleURL(CFBundleCopyExecutableURL(CFBundleGetMainBundle()));

View File

@ -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