summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Include/pyport.h27
-rw-r--r--Objects/frameobject.c4
-rw-r--r--Python/ceval.c6
-rw-r--r--Python/errors.c2
4 files changed, 31 insertions, 8 deletions
diff --git a/Include/pyport.h b/Include/pyport.h
index 20f3db7481..b91fc7468a 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -490,13 +490,36 @@ extern "C" {
* typedef int T1 Py_DEPRECATED(2.4);
* extern int x() Py_DEPRECATED(2.5);
*/
-#if defined(__GNUC__) && ((__GNUC__ >= 4) || \
- (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
+#if defined(__GNUC__) \
+ && ((__GNUC__ >= 4) || (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
#else
#define Py_DEPRECATED(VERSION_UNUSED)
#endif
+
+/* Py_HOT_FUNCTION
+ * The hot attribute on a function is used to inform the compiler that the
+ * function is a hot spot of the compiled program. The function is optimized
+ * more aggressively and on many target it is placed into special subsection of
+ * the text section so all hot functions appears close together improving
+ * locality.
+ *
+ * Usage:
+ * int Py_HOT_FUNCTION x() { return 3; }
+ *
+ * Issue #28618: This attribute must not be abused, otherwise it can have a
+ * negative effect on performance. Only the functions were Python spend most of
+ * its time must use it. Use a profiler when running performance benchmark
+ * suite to find these functions.
+ */
+#if defined(__GNUC__) \
+ && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))
+#define _Py_HOT_FUNCTION __attribute__((hot))
+#else
+#define _Py_HOT_FUNCTION
+#endif
+
/**************************************************************************
Prototypes that are missing from the standard include files on some systems
(and possibly only some versions of such systems.)
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 62f9f34c8e..eed538498c 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -409,7 +409,7 @@ static int numfree = 0; /* number of frames currently in free_list */
/* max value for numfree */
#define PyFrame_MAXFREELIST 200
-static void
+static void _Py_HOT_FUNCTION
frame_dealloc(PyFrameObject *f)
{
PyObject **p, **valuestack;
@@ -605,7 +605,7 @@ int _PyFrame_Init()
return 1;
}
-PyFrameObject *
+PyFrameObject* _Py_HOT_FUNCTION
PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
PyObject *locals)
{
diff --git a/Python/ceval.c b/Python/ceval.c
index 6cc6dfc744..d08b316db4 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -718,7 +718,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
return tstate->interp->eval_frame(f, throwflag);
}
-PyObject *
+PyObject* _Py_HOT_FUNCTION
_PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
{
#ifdef DXPAIRS
@@ -4771,7 +4771,7 @@ if (tstate->use_tracing && tstate->c_profilefunc) { \
x = call; \
}
-static PyObject *
+static PyObject* _Py_HOT_FUNCTION
call_function(PyObject ***pp_stack, Py_ssize_t oparg, PyObject *kwnames)
{
PyObject **pfunc = (*pp_stack) - oparg - 1;
@@ -4844,7 +4844,7 @@ call_function(PyObject ***pp_stack, Py_ssize_t oparg, PyObject *kwnames)
done before evaluating the frame.
*/
-static PyObject*
+static PyObject* _Py_HOT_FUNCTION
_PyFunction_FastCall(PyCodeObject *co, PyObject **args, Py_ssize_t nargs,
PyObject *globals)
{
diff --git a/Python/errors.c b/Python/errors.c
index 0c38f7cf0c..d459fae622 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -158,7 +158,7 @@ PyErr_SetString(PyObject *exception, const char *string)
}
-PyObject *
+PyObject* _Py_HOT_FUNCTION
PyErr_Occurred(void)
{
PyThreadState *tstate = PyThreadState_GET();