bpo-35059: Convert _PyObject_GC_TRACK() to inline function (GH-10643)

* Add _PyObject_ASSERT_FROM() and _PyObject_ASSERT_FAILED_MSG()
  macros.
* PyObject_GC_Track() now calls _PyObject_ASSERT_FAILED_MSG(),
  instead of Py_FatalError(), if the object is already tracked, to
  dump more information on error.
* _PyObject_GC_TRACK() no longer checks if the object is already
  tracked at runtime, use an assertion instead for best performances;
  PyObject_GC_Track() still checks at runtime.
* pycore_object.h now includes pycore_pystate.h.
* Convert _PyObject_GC_TRACK() and _PyObject_GC_UNTRACK() macros to
  inline functions.
This commit is contained in:
Victor Stinner 2018-11-22 01:02:54 +01:00 committed by GitHub
parent f1d002c1e0
commit 271753a27a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 42 deletions

View file

@ -1136,7 +1136,7 @@ _PyObject_DebugTypeStats(FILE *out);
#ifndef Py_LIMITED_API
/* Define a pair of assertion macros:
_PyObject_ASSERT_WITH_MSG() and _PyObject_ASSERT().
_PyObject_ASSERT_FROM(), _PyObject_ASSERT_WITH_MSG() and _PyObject_ASSERT().
These work like the regular C assert(), in that they will abort the
process with a message on stderr if the given condition fails to hold,
@ -1151,21 +1151,24 @@ _PyObject_DebugTypeStats(FILE *out);
will attempt to print to stderr, after the object dump. */
#ifdef NDEBUG
/* No debugging: compile away the assertions: */
# define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) ((void)0)
# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \
((void)0)
#else
/* With debugging: generate checks: */
# define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) \
((expr) \
? (void)(0) \
: _PyObject_AssertFailed((obj), \
Py_STRINGIFY(expr), \
(msg), \
__FILE__, \
__LINE__, \
__func__))
# define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \
((expr) \
? (void)(0) \
: _PyObject_AssertFailed((obj), Py_STRINGIFY(expr), \
(msg), (filename), (lineno), (func)))
#endif
#define _PyObject_ASSERT(obj, expr) _PyObject_ASSERT_WITH_MSG(obj, expr, NULL)
#define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) \
_PyObject_ASSERT_FROM(obj, expr, msg, __FILE__, __LINE__, __func__)
#define _PyObject_ASSERT(obj, expr) \
_PyObject_ASSERT_WITH_MSG(obj, expr, NULL)
#define _PyObject_ASSERT_FAILED_MSG(obj, msg) \
_PyObject_AssertFailed((obj), NULL, (msg), __FILE__, __LINE__, __func__)
/* Declare and define _PyObject_AssertFailed() even when NDEBUG is defined,
to avoid causing compiler/linker errors when building extensions without