Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 56 additions & 43 deletions Doc/c-api/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,45 +105,63 @@ defined closer to where they are useful (e.g. :c:macro:`Py_RETURN_NONE`).
Others of a more general utility are defined here. This is not necessarily a
complete listing.

.. c:macro:: Py_UNREACHABLE()
.. c:macro:: Py_ABS(x)

Use this when you have a code path that cannot be reached by design.
For example, in the ``default:`` clause in a ``switch`` statement for which
all possible values are covered in ``case`` statements. Use this in places
where you might be tempted to put an ``assert(0)`` or ``abort()`` call.
Return the absolute value of ``x``.

In release mode, the macro helps the compiler to optimize the code, and
avoids a warning about unreachable code. For example, the macro is
implemented with ``__builtin_unreachable()`` on GCC in release mode.
.. versionadded:: 3.3

A use for ``Py_UNREACHABLE()`` is following a call a function that
never returns but that is not declared :c:macro:`_Py_NO_RETURN`.
.. c:macro:: Py_CHARMASK(c)

If a code path is very unlikely code but can be reached under exceptional
case, this macro must not be used. For example, under low memory condition
or if a system call returns a value out of the expected range. In this
case, it's better to report the error to the caller. If the error cannot
be reported to caller, :c:func:`Py_FatalError` can be used.
Argument must be a character or an integer in the range [-128, 127] or [0,
255]. This macro returns ``c`` cast to an ``unsigned char``.

.. versionadded:: 3.7
.. c:macro:: Py_DEPRECATED(version)

.. c:macro:: Py_ABS(x)
Use this for deprecated declarations. The macro must be placed before the
symbol name.

Return the absolute value of ``x``.
Example::

Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);

.. versionchanged:: 3.8
MSVC support was added.

.. c:macro:: Py_GETENV(s)

Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the
command line (i.e. if ``Py_IgnoreEnvironmentFlag`` is set).

.. c:macro:: Py_MAX(x, y)

Return the maximum value between ``x`` and ``y``.

.. versionadded:: 3.3

.. c:macro:: Py_MEMBER_SIZE(type, member)

Return the size of a structure (``type``) ``member`` in bytes.

.. versionadded:: 3.6

.. c:macro:: Py_MIN(x, y)

Return the minimum value between ``x`` and ``y``.

.. versionadded:: 3.3

.. c:macro:: Py_MAX(x, y)
.. c:macro:: Py_NO_INLINE

Return the maximum value between ``x`` and ``y``.
Disable inlining on a function. For example, it reduces the C stack
consumption: useful on LTO+PGO builds which heavily inline code (see
:issue:`33720`).

.. versionadded:: 3.3
Usage::

Py_NO_INLINE static int random(void) { return 4; }

.. versionadded:: 3.11

.. c:macro:: Py_STRINGIFY(x)

Expand All @@ -152,21 +170,27 @@ complete listing.

.. versionadded:: 3.4

.. c:macro:: Py_MEMBER_SIZE(type, member)

Return the size of a structure (``type``) ``member`` in bytes.
.. c:macro:: Py_UNREACHABLE()

.. versionadded:: 3.6
Use this when you have a code path that cannot be reached by design.
For example, in the ``default:`` clause in a ``switch`` statement for which
all possible values are covered in ``case`` statements. Use this in places
where you might be tempted to put an ``assert(0)`` or ``abort()`` call.

.. c:macro:: Py_CHARMASK(c)
In release mode, the macro helps the compiler to optimize the code, and
avoids a warning about unreachable code. For example, the macro is
implemented with ``__builtin_unreachable()`` on GCC in release mode.

Argument must be a character or an integer in the range [-128, 127] or [0,
255]. This macro returns ``c`` cast to an ``unsigned char``.
A use for ``Py_UNREACHABLE()`` is following a call a function that
never returns but that is not declared :c:macro:`_Py_NO_RETURN`.

.. c:macro:: Py_GETENV(s)
If a code path is very unlikely code but can be reached under exceptional
case, this macro must not be used. For example, under low memory condition
or if a system call returns a value out of the expected range. In this
case, it's better to report the error to the caller. If the error cannot
be reported to caller, :c:func:`Py_FatalError` can be used.

Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the
command line (i.e. if ``Py_IgnoreEnvironmentFlag`` is set).
.. versionadded:: 3.7

.. c:macro:: Py_UNUSED(arg)

Expand All @@ -175,18 +199,6 @@ complete listing.

.. versionadded:: 3.4

.. c:macro:: Py_DEPRECATED(version)

Use this for deprecated declarations. The macro must be placed before the
symbol name.

Example::

Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);

.. versionchanged:: 3.8
MSVC support was added.

.. c:macro:: PyDoc_STRVAR(name, str)

Creates a variable with name ``name`` that can be used in docstrings.
Expand Down Expand Up @@ -221,6 +233,7 @@ complete listing.
{NULL, NULL}
};


.. _api-objects:

Objects, Types and Reference Counts
Expand Down
7 changes: 1 addition & 6 deletions Include/pymath.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,7 @@ PyAPI_FUNC(void) _Py_set_387controlword(unsigned short);
#pragma float_control(push)
#pragma float_control(precise, on)
#pragma float_control(except, on)
#if defined(_MSC_VER)
__declspec(noinline)
#else /* Linux */
__attribute__((noinline))
#endif /* _MSC_VER */
static double __icc_nan()
Py_NO_INLINE static double __icc_nan()
{
return sqrt(-1.0);
}
Expand Down
25 changes: 13 additions & 12 deletions Include/pyport.h
Original file line number Diff line number Diff line change
Expand Up @@ -557,19 +557,20 @@ extern "C" {
#define _Py_HOT_FUNCTION
#endif

/* _Py_NO_INLINE
* Disable inlining on a function. For example, it helps to reduce the C stack
* consumption.
*
* Usage:
* int _Py_NO_INLINE x(void) { return 3; }
*/
#if defined(_MSC_VER)
# define _Py_NO_INLINE __declspec(noinline)
#elif defined(__GNUC__) || defined(__clang__)
# define _Py_NO_INLINE __attribute__ ((noinline))
// Py_NO_INLINE
// Disable inlining on a function. For example, it reduces the C stack
// consumption: useful on LTO+PGO builds which heavily inline code (see
// bpo-33720).
//
// Usage:
//
// Py_NO_INLINE static int random(void) { return 4; }
#if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER)
# define Py_NO_INLINE __attribute__ ((noinline))
#elif defined(_MSC_VER)
# define Py_NO_INLINE __declspec(noinline)
#else
# define _Py_NO_INLINE
# define Py_NO_INLINE
#endif

/**************************************************************************
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add the :c:macro:`Py_NO_INLINE` macro to disable inlining on a function.
Patch by Victor Stinner.
2 changes: 1 addition & 1 deletion Modules/_functoolsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ partial_dealloc(partialobject *pto)
/* Merging keyword arguments using the vectorcall convention is messy, so
* if we would need to do that, we stop using vectorcall and fall back
* to using partial_call() instead. */
_Py_NO_INLINE static PyObject *
Py_NO_INLINE static PyObject *
partial_vectorcall_fallback(PyThreadState *tstate, partialobject *pto,
PyObject *const *args, size_t nargsf,
PyObject *kwnames)
Expand Down
2 changes: 1 addition & 1 deletion Modules/_io/bytesio.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ resize_buffer(bytesio *self, size_t size)
object. Returns the number of bytes written, or -1 on error.
Inlining is disabled because it's significantly decreases performance
of writelines() in PGO build. */
_Py_NO_INLINE static Py_ssize_t
Py_NO_INLINE static Py_ssize_t
write_bytes(bytesio *self, PyObject *b)
{
if (check_closed(self)) {
Expand Down
4 changes: 2 additions & 2 deletions Modules/_posixsubprocess.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ reset_signal_handlers(const sigset_t *child_sigmask)
* If vfork-unsafe functionality is desired after vfork(), consider using
* syscall() to obtain it.
*/
_Py_NO_INLINE static void
Py_NO_INLINE static void
child_exec(char *const exec_array[],
char *const argv[],
char *const envp[],
Expand Down Expand Up @@ -650,7 +650,7 @@ child_exec(char *const exec_array[],
* child_exec() should not be inlined to avoid spurious -Wclobber warnings from
* GCC (see bpo-35823).
*/
_Py_NO_INLINE static pid_t
Py_NO_INLINE static pid_t
do_fork_exec(char *const exec_array[],
char *const argv[],
char *const envp[],
Expand Down
2 changes: 1 addition & 1 deletion Python/marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,7 @@ r_float_bin(RFILE *p)

/* Issue #33720: Disable inlining for reducing the C stack consumption
on PGO builds. */
_Py_NO_INLINE static double
Py_NO_INLINE static double
r_float_str(RFILE *p)
{
int n;
Expand Down