Skip to content

bpo-35081: Move _PyObject_GC_TRACK() to pycore_object.h #10272

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
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
3 changes: 0 additions & 3 deletions Include/internal/pycore_mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,6 @@ struct _gc_runtime_state {

PyAPI_FUNC(void) _PyGC_Initialize(struct _gc_runtime_state *);

#define _PyGC_generation0 _PyRuntime.gc.generation0


/* Set the memory allocator of the specified domain to the default.
Save the old allocator into *old_alloc if it's non-NULL.
Return on success, or return -1 if the domain is unknown. */
Expand Down
54 changes: 54 additions & 0 deletions Include/internal/pycore_object.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef Py_INTERNAL_OBECT_H
#define Py_INTERNAL_OBECT_H
#ifdef __cplusplus
extern "C" {
#endif

#ifndef Py_BUILD_CORE
# error "Py_BUILD_CORE must be defined to include this header"
#endif

#include "pycore_state.h"

/* 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.
*/
#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.
*/
#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_OBECT_H */
40 changes: 0 additions & 40 deletions Include/objimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,6 @@ typedef struct {
uintptr_t _gc_prev;
} PyGC_Head;

extern PyGC_Head *_PyGC_generation0;

#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1)

/* Bit flags for _gc_prev */
Expand Down Expand Up @@ -310,44 +308,6 @@ extern PyGC_Head *_PyGC_generation0;
#define _PyGC_FINALIZED(o) _PyGCHead_FINALIZED(_Py_AS_GC(o))
#define _PyGC_SET_FINALIZED(o) _PyGCHead_SET_FINALIZED(_Py_AS_GC(o))

/* 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: _PyGC_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.
*/
#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*)(_PyGC_generation0->_gc_prev); \
_PyGCHead_SET_NEXT(last, g); \
_PyGCHead_SET_PREV(g, last); \
_PyGCHead_SET_NEXT(g, _PyGC_generation0); \
_PyGC_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.
*/
#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);

/* True if the object is currently tracked by the GC. */
#define _PyObject_GC_IS_TRACKED(o) (_Py_AS_GC(o)->_gc_next != 0)

Expand Down
1 change: 1 addition & 0 deletions Modules/_io/bufferedio.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "structmember.h"
#include "pythread.h"
Expand Down
1 change: 1 addition & 0 deletions Modules/_io/bytesio.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "Python.h"
#include "structmember.h" /* for offsetof() */
#include "_iomodule.h"
#include "pycore_object.h"

/*[clinic input]
module _io
Expand Down
1 change: 1 addition & 0 deletions Modules/_io/fileio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 <sys/types.h>
Expand Down
1 change: 1 addition & 0 deletions Modules/_io/iobase.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "structmember.h"
#include "pycore_object.h"
#include "_iomodule.h"

/*[clinic input]
Expand Down
1 change: 1 addition & 0 deletions Modules/_io/stringio.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "Python.h"
#include "structmember.h"
#include "accu.h"
#include "pycore_object.h"
#include "_iomodule.h"

/* Implementation note: the buffer is always at least one character longer
Expand Down
1 change: 1 addition & 0 deletions Modules/_io/textio.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "pycore_object.h"
#include "structmember.h"
#include "_iomodule.h"

Expand Down
3 changes: 2 additions & 1 deletion Modules/_io/winconsoleio.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "pycore_object.h"

#ifdef MS_WINDOWS

Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions Modules/_queuemodule.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "Python.h"
#include "structmember.h" /* offsetof */
#include "pythread.h"
#include "structmember.h" /* offsetof */

/*[clinic input]
module _queue
Expand All @@ -26,7 +26,7 @@ typedef struct {
static void
simplequeue_dealloc(simplequeueobject *self)
{
_PyObject_GC_UNTRACK(self);
PyObject_GC_UnTrack(self);
if (self->lock != NULL) {
/* Unlock the lock so it's safe to free it */
if (self->locked > 0)
Expand Down
1 change: 1 addition & 0 deletions Modules/gcmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "Python.h"
#include "pycore_context.h"
#include "pycore_mem.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "frameobject.h" /* for PyFrame_ClearFreeList */
#include "pydtrace.h"
Expand Down
7 changes: 4 additions & 3 deletions Objects/bytearrayobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "pycore_mem.h"
#include "pycore_state.h"
#include "structmember.h"
#include "bytes_methods.h"
#include "bytesobject.h"
#include "pycore_mem.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "pystrhex.h"
#include "structmember.h"

/*[clinic input]
class bytearray "PyByteArrayObject *" "&PyByteArray_Type"
Expand Down
4 changes: 2 additions & 2 deletions Objects/bytesobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
#define PY_SSIZE_T_CLEAN

#include "Python.h"
#include "bytes_methods.h"
#include "pycore_mem.h"
#include "pycore_object.h"
#include "pycore_state.h"

#include "bytes_methods.h"
#include "pystrhex.h"
#include <stddef.h>

Expand Down
3 changes: 2 additions & 1 deletion Objects/call.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "Python.h"
#include "pycore_state.h"
#include "frameobject.h"
#include "pycore_object.h"
#include "pycore_state.h"


int
Expand Down
1 change: 1 addition & 0 deletions Objects/cellobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "Python.h"
#include "pycore_mem.h"
#include "pycore_object.h"
#include "pycore_state.h"

PyObject *
Expand Down
1 change: 1 addition & 0 deletions Objects/classobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "Python.h"
#include "pycore_mem.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "structmember.h"

Expand Down
1 change: 1 addition & 0 deletions Objects/descrobject.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* Descriptors -- a new, flexible way to describe attributes */

#include "Python.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "structmember.h" /* Why is this not included in Python.h? */

Expand Down
3 changes: 2 additions & 1 deletion Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,9 @@ converting the dict to the combined table.
#define PyDict_MINSIZE 8

#include "Python.h"
#include "pycore_state.h"
#include "dict-common.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "stringlib/eq.h" /* to get unicode_eq() */

/*[clinic input]
Expand Down
1 change: 1 addition & 0 deletions Objects/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "pycore_mem.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "structmember.h"
#include "osdefs.h"
Expand Down
4 changes: 2 additions & 2 deletions Objects/frameobject.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/* Frame object implementation */

#include "Python.h"
#include "pycore_state.h"

#include "code.h"
#include "frameobject.h"
#include "opcode.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "structmember.h"

#define OFF(x) offsetof(PyFrameObject, x)
Expand Down
3 changes: 2 additions & 1 deletion Objects/funcobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
/* Function object implementation */

#include "Python.h"
#include "code.h"
#include "pycore_mem.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "code.h"
#include "structmember.h"

PyObject *
Expand Down
5 changes: 3 additions & 2 deletions Objects/genobject.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/* Generator object implementation */

#include "Python.h"
#include "pycore_state.h"
#include "frameobject.h"
#include "structmember.h"
#include "opcode.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "structmember.h"

static PyObject *gen_close(PyGenObject *, PyObject *);
static PyObject *async_gen_asend_new(PyAsyncGenObject *, PyObject *);
Expand Down
1 change: 1 addition & 0 deletions Objects/iterobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "Python.h"
#include "pycore_mem.h"
#include "pycore_object.h"
#include "pycore_state.h"

typedef struct {
Expand Down
3 changes: 2 additions & 1 deletion Objects/listobject.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* List object implementation */

#include "Python.h"
#include "pycore_state.h"
#include "accu.h"
#include "pycore_object.h"
#include "pycore_state.h"

#ifdef STDC_HEADERS
#include <stddef.h>
Expand Down
1 change: 1 addition & 0 deletions Objects/memoryobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "Python.h"
#include "pycore_mem.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "pystrhex.h"
#include <stddef.h>
Expand Down
1 change: 1 addition & 0 deletions Objects/methodobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "Python.h"
#include "pycore_mem.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "structmember.h"

Expand Down
3 changes: 2 additions & 1 deletion Objects/odictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,10 @@ Potential Optimizations
*/

#include "Python.h"
#include "dict-common.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "structmember.h"
#include "dict-common.h"
#include <stddef.h>

#include "clinic/odictobject.c.h"
Expand Down
1 change: 1 addition & 0 deletions Objects/setobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*/

#include "Python.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "structmember.h"

Expand Down
1 change: 1 addition & 0 deletions Objects/sliceobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ this type and there is exactly one in existence.

#include "Python.h"
#include "pycore_mem.h"
#include "pycore_object.h"
#include "pycore_state.h"
#include "structmember.h"

Expand Down
Loading