elog_ereport_attribute_cold.patch
application/octet-stream
Filename: elog_ereport_attribute_cold.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/utils/error/elog.c | 13 | 0 |
| src/include/c.h | 15 | 0 |
| src/include/utils/elog.h | 16 | 0 |
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index e976201030..8076e8af24 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -219,6 +219,19 @@ err_gettext(const char *str)
#endif
}
+#if defined(HAVE_PG_ATTRIBUTE_HOT_AND_COLD) && defined(HAVE__BUILTIN_CONSTANT_P)
+/*
+ * 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);
+}
+#endif
/*
* errstart --- begin an error-reporting cycle
diff --git a/src/include/c.h b/src/include/c.h
index d72b23afe4..087b8af6cb 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -178,6 +178,21 @@
#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.
+ * These are supported from GCC >= 4.3 and clang >= 3.2
+ */
+#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || \
+ (defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 2)))
+#define HAVE_PG_ATTRIBUTE_HOT_AND_COLD 1
+#define pg_attribute_hot __attribute__((hot))
+#define pg_attribute_cold __attribute__((cold))
+#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..97fb4d74d2 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -121,6 +121,18 @@
*----------
*/
#ifdef HAVE__BUILTIN_CONSTANT_P
+#ifdef HAVE_PG_ATTRIBUTE_HOT_AND_COLD
+#define ereport_domain(elevel, domain, ...) \
+ do { \
+ pg_prevent_errno_in_scope(); \
+ 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(); \
+ } while(0)
+#else /* !HAVE_PG_ATTRIBUTE_HOT_AND_COLD */
#define ereport_domain(elevel, domain, ...) \
do { \
pg_prevent_errno_in_scope(); \
@@ -129,6 +141,7 @@
if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \
pg_unreachable(); \
} while(0)
+#endif /* HAVE_PG_ATTRIBUTE_HOT_AND_COLD */
#else /* !HAVE__BUILTIN_CONSTANT_P */
#define ereport_domain(elevel, domain, ...) \
do { \
@@ -146,6 +159,9 @@
#define TEXTDOMAIN NULL
+#ifdef HAVE_PG_ATTRIBUTE_HOT_AND_COLD
+extern bool pg_attribute_cold errstart_cold(int elevel, const char *domain);
+#endif
extern bool errstart(int elevel, const char *domain);
extern void errfinish(const char *filename, int lineno, const char *funcname);