diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index e976201030..b2e761fdf2 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -219,6 +219,17 @@ err_gettext(const char *str) #endif } +/* + * errstart_cold + * A simple wrapper around errstart, but hinted to be cold so that the + * compiler is more likely to put error code in a cold area away from the + * main function body. + */ +bool pg_attribute_cold +errstart_cold(int elevel, const char *domain) +{ + return errstart(elevel, domain); +} /* * errstart --- begin an error-reporting cycle diff --git a/src/include/c.h b/src/include/c.h index a904b49a37..317e76ed3d 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -178,6 +178,29 @@ #define pg_noinline #endif +/* + * Marking certain functions as "hot" or "cold" can be useful to assist the + * compiler in arranging the assembly code in a more efficient way. + */ +#if defined(__has_attribute) + +#if __has_attribute (cold) +#define pg_attribute_cold __attribute__((cold)) +#else +#define pg_attribute_cold +#endif + +#if __has_attribute (hot) +#define pg_attribute_hot __attribute__((hot)) +#else +#define pg_attribute_hot +#endif + +#else +#define pg_attribute_hot +#define pg_attribute_cold +#endif + /* * Mark a point as unreachable in a portable fashion. This should preferably * be something that the compiler understands, to aid code generation. diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 1e09ee0541..5dfecc55e5 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -124,7 +124,9 @@ #define ereport_domain(elevel, domain, ...) \ do { \ pg_prevent_errno_in_scope(); \ - if (errstart(elevel, domain)) \ + if (__builtin_constant_p(elevel) && (elevel) >= ERROR ? \ + errstart_cold(elevel, domain) : \ + errstart(elevel, domain)) \ __VA_ARGS__, errfinish(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \ if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \ pg_unreachable(); \ @@ -146,7 +148,9 @@ #define TEXTDOMAIN NULL +extern bool pg_attribute_cold errstart_cold(int elevel, const char *domain); extern bool errstart(int elevel, const char *domain); + extern void errfinish(const char *filename, int lineno, const char *funcname); extern int errcode(int sqlerrcode);