Mark some functions as cold

Add Q_DECL_COLD_FUNCTION (__attribute__((cold))) to tell the compiler
that the following functions are not usually executed in normal programs:

- qWarning/qCritical/qFatal
- qTerminate
- assertion failure
- qBadAlloc

The effect of the attribute is that

1. These functions get put into their own section, .text.unlikely,
   and will be optimized for size, not speed.
2. Conditions that lead to one of these functions are automatically
   marked as unlikely (something we have done manually in the past)
3. (anecdotal) the compiler is less likely to inline these functions

Text size effect of this change over all of QtBase: ~27KiB text size
saved, of which 11KiB in QtCore alone.

Change-Id: If308d4a4b9ff8f7934316c54b161a78ebe3f4205
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2017-11-21 10:41:45 +01:00
parent 7967c40303
commit c6497e3eac
3 changed files with 18 additions and 3 deletions

View File

@ -243,6 +243,7 @@
# define Q_REQUIRED_RESULT __attribute__ ((__warn_unused_result__)) # define Q_REQUIRED_RESULT __attribute__ ((__warn_unused_result__))
# define Q_DECL_PURE_FUNCTION __attribute__((pure)) # define Q_DECL_PURE_FUNCTION __attribute__((pure))
# define Q_DECL_CONST_FUNCTION __attribute__((const)) # define Q_DECL_CONST_FUNCTION __attribute__((const))
# define Q_DECL_COLD_FUNCTION __attribute__((cold))
# if !defined(QT_MOC_CPP) # if !defined(QT_MOC_CPP)
# define Q_PACKED __attribute__ ((__packed__)) # define Q_PACKED __attribute__ ((__packed__))
# ifndef __ARM_EABI__ # ifndef __ARM_EABI__
@ -1275,6 +1276,9 @@
#ifndef Q_DECL_CONST_FUNCTION #ifndef Q_DECL_CONST_FUNCTION
# define Q_DECL_CONST_FUNCTION Q_DECL_PURE_FUNCTION # define Q_DECL_CONST_FUNCTION Q_DECL_PURE_FUNCTION
#endif #endif
#ifndef Q_DECL_COLD_FUNCTION
# define Q_DECL_COLD_FUNCTION
#endif
#ifndef QT_MAKE_UNCHECKED_ARRAY_ITERATOR #ifndef QT_MAKE_UNCHECKED_ARRAY_ITERATOR
# define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) (x) # define QT_MAKE_UNCHECKED_ARRAY_ITERATOR(x) (x)
#endif #endif

View File

@ -706,7 +706,7 @@ inline void qt_noop(void) {}
# define QT_CATCH(A) catch (A) # define QT_CATCH(A) catch (A)
# define QT_THROW(A) throw A # define QT_THROW(A) throw A
# define QT_RETHROW throw # define QT_RETHROW throw
Q_NORETURN Q_CORE_EXPORT void qTerminate() Q_DECL_NOTHROW; Q_NORETURN Q_DECL_COLD_FUNCTION Q_CORE_EXPORT void qTerminate() Q_DECL_NOTHROW;
# ifdef Q_COMPILER_NOEXCEPT # ifdef Q_COMPILER_NOEXCEPT
# define QT_TERMINATE_ON_EXCEPTION(expr) do { expr; } while (false) # define QT_TERMINATE_ON_EXCEPTION(expr) do { expr; } while (false)
# else # else
@ -749,11 +749,13 @@ Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qSharedBuild() Q_DECL_NOTHROW;
#endif #endif
class QString; class QString;
Q_DECL_COLD_FUNCTION
Q_CORE_EXPORT QString qt_error_string(int errorCode = -1); Q_CORE_EXPORT QString qt_error_string(int errorCode = -1);
#ifndef Q_CC_MSVC #ifndef Q_CC_MSVC
Q_NORETURN Q_NORETURN
#endif #endif
Q_DECL_COLD_FUNCTION
Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line) Q_DECL_NOTHROW; Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line) Q_DECL_NOTHROW;
#if !defined(Q_ASSERT) #if !defined(Q_ASSERT)
@ -771,6 +773,7 @@ Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line)
#ifndef Q_CC_MSVC #ifndef Q_CC_MSVC
Q_NORETURN Q_NORETURN
#endif #endif
Q_DECL_COLD_FUNCTION
Q_CORE_EXPORT void qt_assert_x(const char *where, const char *what, const char *file, int line) Q_DECL_NOTHROW; Q_CORE_EXPORT void qt_assert_x(const char *where, const char *what, const char *file, int line) Q_DECL_NOTHROW;
#if !defined(Q_ASSERT_X) #if !defined(Q_ASSERT_X)
@ -782,6 +785,7 @@ Q_CORE_EXPORT void qt_assert_x(const char *where, const char *what, const char *
#endif #endif
Q_NORETURN Q_CORE_EXPORT void qt_check_pointer(const char *, int) Q_DECL_NOTHROW; Q_NORETURN Q_CORE_EXPORT void qt_check_pointer(const char *, int) Q_DECL_NOTHROW;
Q_DECL_COLD_FUNCTION
Q_CORE_EXPORT void qBadAlloc(); Q_CORE_EXPORT void qBadAlloc();
#ifdef QT_NO_EXCEPTIONS #ifdef QT_NO_EXCEPTIONS

View File

@ -97,7 +97,9 @@ public:
void noDebug(const char *, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3) void noDebug(const char *, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3)
{} {}
void info(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3); void info(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
Q_DECL_COLD_FUNCTION
void warning(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3); void warning(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
Q_DECL_COLD_FUNCTION
void critical(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3); void critical(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
typedef const QLoggingCategory &(*CategoryFunction)(); typedef const QLoggingCategory &(*CategoryFunction)();
@ -106,14 +108,19 @@ public:
void debug(CategoryFunction catFunc, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4); void debug(CategoryFunction catFunc, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
void info(const QLoggingCategory &cat, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4); void info(const QLoggingCategory &cat, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
void info(CategoryFunction catFunc, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4); void info(CategoryFunction catFunc, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
Q_DECL_COLD_FUNCTION
void warning(const QLoggingCategory &cat, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4); void warning(const QLoggingCategory &cat, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
Q_DECL_COLD_FUNCTION
void warning(CategoryFunction catFunc, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4); void warning(CategoryFunction catFunc, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
Q_DECL_COLD_FUNCTION
void critical(const QLoggingCategory &cat, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4); void critical(const QLoggingCategory &cat, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
Q_DECL_COLD_FUNCTION
void critical(CategoryFunction catFunc, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4); void critical(CategoryFunction catFunc, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
#ifndef Q_CC_MSVC #ifndef Q_CC_MSVC
Q_NORETURN Q_NORETURN
#endif #endif
Q_DECL_COLD_FUNCTION
void fatal(const char *msg, ...) const Q_DECL_NOTHROW Q_ATTRIBUTE_FORMAT_PRINTF(2, 3); void fatal(const char *msg, ...) const Q_DECL_NOTHROW Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM
@ -179,8 +186,8 @@ private:
Q_CORE_EXPORT void qt_message_output(QtMsgType, const QMessageLogContext &context, Q_CORE_EXPORT void qt_message_output(QtMsgType, const QMessageLogContext &context,
const QString &message); const QString &message);
Q_CORE_EXPORT void qErrnoWarning(int code, const char *msg, ...); Q_CORE_EXPORT Q_DECL_COLD_FUNCTION void qErrnoWarning(int code, const char *msg, ...);
Q_CORE_EXPORT void qErrnoWarning(const char *msg, ...); Q_CORE_EXPORT Q_DECL_COLD_FUNCTION void qErrnoWarning(const char *msg, ...);
#if QT_DEPRECATED_SINCE(5, 0)// deprecated. Use qInstallMessageHandler instead! #if QT_DEPRECATED_SINCE(5, 0)// deprecated. Use qInstallMessageHandler instead!
typedef void (*QtMsgHandler)(QtMsgType, const char *); typedef void (*QtMsgHandler)(QtMsgType, const char *);