From bcda8f1d42a98d9022736dd52d855be8e220fe15 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 21 Nov 2018 22:27:47 +0100 Subject: [PATCH] bpo-35081: Add Include/internal/pycore_object.h (GH-10640) Move _PyObject_GC_TRACK() and _PyObject_GC_UNTRACK() from Include/objimpl.h to Include/internal/pycore_object.h. --- Include/internal/pycore_object.h | 56 ++++++++++++++++++++++++++++++++ Include/objimpl.h | 45 ------------------------- Modules/_io/bufferedio.c | 1 + Modules/_io/bytesio.c | 1 + Modules/_io/fileio.c | 1 + Modules/_io/iobase.c | 1 + Modules/_io/stringio.c | 1 + Modules/_io/textio.c | 1 + Modules/_io/winconsoleio.c | 3 +- Modules/gcmodule.c | 1 + Objects/bytearrayobject.c | 1 + Objects/bytesobject.c | 1 + Objects/call.c | 1 + Objects/cellobject.c | 1 + Objects/classobject.c | 1 + Objects/descrobject.c | 1 + Objects/dictobject.c | 1 + Objects/exceptions.c | 1 + Objects/frameobject.c | 1 + Objects/funcobject.c | 1 + Objects/genobject.c | 1 + Objects/iterobject.c | 1 + Objects/listobject.c | 1 + Objects/memoryobject.c | 1 + Objects/methodobject.c | 1 + Objects/odictobject.c | 1 + Objects/setobject.c | 1 + Objects/sliceobject.c | 1 + Objects/tupleobject.c | 1 + Objects/typeobject.c | 1 + Objects/unicodeobject.c | 1 + Python/ceval.c | 1 + Python/context.c | 5 +-- Python/hamt.c | 5 +-- 34 files changed, 93 insertions(+), 50 deletions(-) create mode 100644 Include/internal/pycore_object.h diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h new file mode 100644 index 00000000000..a2638344b16 --- /dev/null +++ b/Include/internal/pycore_object.h @@ -0,0 +1,56 @@ +#ifndef Py_INTERNAL_OBJECT_H +#define Py_INTERNAL_OBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_BUILTIN) +# error "this header requires Py_BUILD_CORE or Py_BUILD_CORE_BUILTIN defined" +#endif + +/* Tell the GC to track this object. + * + * NB: While the object is tracked by the collector, it must be safe to call the + * ob_traverse method. + * + * Internal note: _PyRuntime.gc.generation0->_gc_prev doesn't have any bit flags + * because it's not object header. So we don't use _PyGCHead_PREV() and + * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations. + * + * The PyObject_GC_Track() function is the public version of this macro. + */ +#define _PyObject_GC_TRACK(o) do { \ + PyGC_Head *g = _Py_AS_GC(o); \ + if (g->_gc_next != 0) { \ + Py_FatalError("GC object already tracked"); \ + } \ + assert((g->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0); \ + PyGC_Head *last = (PyGC_Head*)(_PyRuntime.gc.generation0->_gc_prev); \ + _PyGCHead_SET_NEXT(last, g); \ + _PyGCHead_SET_PREV(g, last); \ + _PyGCHead_SET_NEXT(g, _PyRuntime.gc.generation0); \ + _PyRuntime.gc.generation0->_gc_prev = (uintptr_t)g; \ + } while (0); + +/* Tell the GC to stop tracking this object. + * + * Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING must + * be cleared. But _PyGC_PREV_MASK_FINALIZED bit is kept. + * + * The PyObject_GC_UnTrack() function is the public version of this macro. + */ +#define _PyObject_GC_UNTRACK(o) do { \ + PyGC_Head *g = _Py_AS_GC(o); \ + PyGC_Head *prev = _PyGCHead_PREV(g); \ + PyGC_Head *next = _PyGCHead_NEXT(g); \ + assert(next != NULL); \ + _PyGCHead_SET_NEXT(prev, next); \ + _PyGCHead_SET_PREV(next, prev); \ + g->_gc_next = 0; \ + g->_gc_prev &= _PyGC_PREV_MASK_FINALIZED; \ + } while (0); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_OBJECT_H */ diff --git a/Include/objimpl.h b/Include/objimpl.h index b51b751b9c8..c455d4bebbd 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -323,51 +323,6 @@ typedef struct { _PyGCHead_SET_FINALIZED(_Py_AS_GC(o)) #endif /* !defined(Py_LIMITED_API) */ - -#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) -/* Tell the GC to track this object. - * - * NB: While the object is tracked by the collector, it must be safe to call the - * ob_traverse method. - * - * Internal note: _PyRuntime.gc.generation0->_gc_prev doesn't have any bit flags - * because it's not object header. So we don't use _PyGCHead_PREV() and - * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations. - * - * The PyObject_GC_Track() function is the public version of this macro. - */ -#define _PyObject_GC_TRACK(o) do { \ - PyGC_Head *g = _Py_AS_GC(o); \ - if (g->_gc_next != 0) { \ - Py_FatalError("GC object already tracked"); \ - } \ - assert((g->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0); \ - PyGC_Head *last = (PyGC_Head*)(_PyRuntime.gc.generation0->_gc_prev); \ - _PyGCHead_SET_NEXT(last, g); \ - _PyGCHead_SET_PREV(g, last); \ - _PyGCHead_SET_NEXT(g, _PyRuntime.gc.generation0); \ - _PyRuntime.gc.generation0->_gc_prev = (uintptr_t)g; \ - } while (0); - -/* Tell the GC to stop tracking this object. - * - * Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING must - * be cleared. But _PyGC_PREV_MASK_FINALIZED bit is kept. - * - * The PyObject_GC_UnTrack() function is the public version of this macro. - */ -#define _PyObject_GC_UNTRACK(o) do { \ - PyGC_Head *g = _Py_AS_GC(o); \ - PyGC_Head *prev = _PyGCHead_PREV(g); \ - PyGC_Head *next = _PyGCHead_NEXT(g); \ - assert(next != NULL); \ - _PyGCHead_SET_NEXT(prev, next); \ - _PyGCHead_SET_PREV(next, prev); \ - g->_gc_next = 0; \ - g->_gc_prev &= _PyGC_PREV_MASK_FINALIZED; \ - } while (0); -#endif /* defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) */ - #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t size); PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size); diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index e1e45dc8fae..6f855b9edd0 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -9,6 +9,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "structmember.h" #include "pythread.h" diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index a50add2389e..8e54ec8e99c 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_object.h" #include "structmember.h" /* for offsetof() */ #include "_iomodule.h" diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index ffcb7301295..c502c430134 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -2,6 +2,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" #include "structmember.h" #ifdef HAVE_SYS_TYPES_H #include diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 5b71732ef19..9b063cd372f 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -10,6 +10,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" #include "structmember.h" #include "_iomodule.h" diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 793fa1ee150..bb5c3736a77 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -2,6 +2,7 @@ #include "Python.h" #include "structmember.h" #include "pycore_accu.h" +#include "pycore_object.h" #include "_iomodule.h" /* Implementation note: the buffer is always at least one character longer diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 8924834eb81..645d7123324 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -8,6 +8,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" #include "structmember.h" #include "_iomodule.h" diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 148255c354a..824690ff58d 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -8,6 +8,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" #ifdef MS_WINDOWS @@ -556,7 +557,7 @@ read_console_w(HANDLE handle, DWORD maxlen, DWORD *readlen) { Py_BEGIN_ALLOW_THREADS DWORD off = 0; while (off < maxlen) { - DWORD n = (DWORD)-1; + DWORD n = (DWORD)-1; DWORD len = min(maxlen - off, BUFSIZ); SetLastError(0); BOOL res = ReadConsoleW(handle, &buf[off], len, &n, NULL); diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 48b470006c4..2cbf73866d1 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -25,6 +25,7 @@ #include "Python.h" #include "pycore_context.h" +#include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "frameobject.h" /* for PyFrame_ClearFreeList */ diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 561b06cdf96..14426538194 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2,6 +2,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "structmember.h" diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index fac12f55210..bed75ee49e2 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3,6 +3,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" diff --git a/Objects/call.c b/Objects/call.c index 7c452b99d11..ce346c29348 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "frameobject.h" diff --git a/Objects/cellobject.c b/Objects/cellobject.c index 7605bcf7bc9..6b7136c4127 100644 --- a/Objects/cellobject.c +++ b/Objects/cellobject.c @@ -1,6 +1,7 @@ /* Cell object implementation */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" diff --git a/Objects/classobject.c b/Objects/classobject.c index 79b0562f7d5..6d1f05ccd3a 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -1,6 +1,7 @@ /* Class object implementation (dead now except for methods) */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "structmember.h" diff --git a/Objects/descrobject.c b/Objects/descrobject.c index ca814bf78a6..dd3c5014aea 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1,6 +1,7 @@ /* Descriptors -- a new, flexible way to describe attributes */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "structmember.h" /* Why is this not included in Python.h? */ diff --git a/Objects/dictobject.c b/Objects/dictobject.c index df92bfd6a97..24561dd42c2 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -111,6 +111,7 @@ converting the dict to the combined table. #define PyDict_MINSIZE 8 #include "Python.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "dict-common.h" #include "stringlib/eq.h" /* to get unicode_eq() */ diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 5ab127111ca..cecbf977a32 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -6,6 +6,7 @@ #define PY_SSIZE_T_CLEAN #include +#include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "structmember.h" diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 70cf5807130..b1a83d82a39 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -1,6 +1,7 @@ /* Frame object implementation */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "code.h" diff --git a/Objects/funcobject.c b/Objects/funcobject.c index a8e11a9a2d3..982df5434d2 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -2,6 +2,7 @@ /* Function object implementation */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "code.h" diff --git a/Objects/genobject.c b/Objects/genobject.c index 716bd6d067b..3279a0947e8 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1,6 +1,7 @@ /* Generator object implementation */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "frameobject.h" #include "structmember.h" diff --git a/Objects/iterobject.c b/Objects/iterobject.c index 64bf92382be..ada1bdc7e87 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -1,6 +1,7 @@ /* Iterator objects */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" diff --git a/Objects/listobject.c b/Objects/listobject.c index 44160abae6e..6da8391fc27 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -1,6 +1,7 @@ /* List object implementation */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "pycore_accu.h" diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 060ae4dd3cd..0f528eec68b 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -1,6 +1,7 @@ /* Memoryview object implementation */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "pystrhex.h" diff --git a/Objects/methodobject.c b/Objects/methodobject.c index cfea8cf410d..23325e2a1b3 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -2,6 +2,7 @@ /* Method object implementation */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "structmember.h" diff --git a/Objects/odictobject.c b/Objects/odictobject.c index 13bc972039f..bdd61080d18 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -465,6 +465,7 @@ later: */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "structmember.h" #include "dict-common.h" diff --git a/Objects/setobject.c b/Objects/setobject.c index b11cb3a5869..c2a1467ba61 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -32,6 +32,7 @@ */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "structmember.h" diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 1f79faa3e6c..c60483ea949 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -14,6 +14,7 @@ this type and there is exactly one in existence. */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pymem.h" #include "pycore_pystate.h" #include "structmember.h" diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index e7ba09d71d3..83c63e089c3 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -2,6 +2,7 @@ /* Tuple object implementation */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "pycore_accu.h" diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 4d599bf5163..2345b7c07dc 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1,6 +1,7 @@ /* Type object implementation */ #include "Python.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "frameobject.h" #include "structmember.h" diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 04ca5f33444..d22b277a51c 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -41,6 +41,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define PY_SSIZE_T_CLEAN #include "Python.h" #include "pycore_fileutils.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "ucnhash.h" #include "bytes_methods.h" diff --git a/Python/ceval.c b/Python/ceval.c index 9c0ab0663b1..7b2465592a4 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -10,6 +10,7 @@ #define PY_LOCAL_AGGRESSIVE #include "Python.h" +#include "pycore_object.h" #include "pycore_pystate.h" #include "code.h" diff --git a/Python/context.c b/Python/context.c index b548ffee3bc..302f7696bb6 100644 --- a/Python/context.c +++ b/Python/context.c @@ -1,9 +1,10 @@ #include "Python.h" -#include "structmember.h" -#include "pycore_pystate.h" #include "pycore_context.h" #include "pycore_hamt.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "structmember.h" #define CONTEXT_FREELIST_MAXLEN 255 diff --git a/Python/hamt.c b/Python/hamt.c index 3fe70b40faf..d734d6ed07f 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -1,8 +1,9 @@ #include "Python.h" -#include "structmember.h" -#include "pycore_pystate.h" #include "pycore_hamt.h" +#include "pycore_object.h" +#include "pycore_pystate.h" +#include "structmember.h" /* This file provides an implemention of an immutable mapping using the