Skip to content

gh-105268: Add _Py_FROM_GC() function to pycore_gc.h #105362

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

Merged
merged 1 commit into from
Jun 6, 2023
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
23 changes: 17 additions & 6 deletions Include/internal/pycore_gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,21 @@ typedef struct {
uintptr_t _gc_prev;
} PyGC_Head;

#define _PyGC_Head_UNUSED PyGC_Head


/* Get an object's GC head */
static inline PyGC_Head* _Py_AS_GC(PyObject *op) {
return (_Py_CAST(PyGC_Head*, op) - 1);
char *gc = ((char*)op) - sizeof(PyGC_Head);
return (PyGC_Head*)gc;
}
#define _PyGC_Head_UNUSED PyGC_Head

/* Get the object given the GC head */
static inline PyObject* _Py_FROM_GC(PyGC_Head *gc) {
char *op = ((char *)gc) + sizeof(PyGC_Head);
return (PyObject *)op;
}


/* True if the object is currently tracked by the GC. */
static inline int _PyObject_GC_IS_TRACKED(PyObject *op) {
Expand Down Expand Up @@ -57,19 +68,19 @@ static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) {
// But it is always 0 for normal code.
static inline PyGC_Head* _PyGCHead_NEXT(PyGC_Head *gc) {
uintptr_t next = gc->_gc_next;
return _Py_CAST(PyGC_Head*, next);
return (PyGC_Head*)next;
}
static inline void _PyGCHead_SET_NEXT(PyGC_Head *gc, PyGC_Head *next) {
gc->_gc_next = _Py_CAST(uintptr_t, next);
gc->_gc_next = (uintptr_t)next;
}

// Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags.
static inline PyGC_Head* _PyGCHead_PREV(PyGC_Head *gc) {
uintptr_t prev = (gc->_gc_prev & _PyGC_PREV_MASK);
return _Py_CAST(PyGC_Head*, prev);
return (PyGC_Head*)prev;
}
static inline void _PyGCHead_SET_PREV(PyGC_Head *gc, PyGC_Head *prev) {
uintptr_t uprev = _Py_CAST(uintptr_t, prev);
uintptr_t uprev = (uintptr_t)prev;
assert((uprev & ~_PyGC_PREV_MASK) == 0);
gc->_gc_prev = ((gc->_gc_prev & ~_PyGC_PREV_MASK) | uprev);
}
Expand Down
6 changes: 3 additions & 3 deletions Include/internal/pycore_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,9 @@ _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(PyObject *op)
static inline int
_PyObject_IS_GC(PyObject *obj)
{
return (PyType_IS_GC(Py_TYPE(obj))
&& (Py_TYPE(obj)->tp_is_gc == NULL
|| Py_TYPE(obj)->tp_is_gc(obj)));
PyTypeObject *type = Py_TYPE(obj);
return (PyType_IS_GC(type)
&& (type->tp_is_gc == NULL || type->tp_is_gc(obj)));
}

// Fast inlined version of PyType_IS_GC()
Expand Down
14 changes: 6 additions & 8 deletions Modules/gcmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,9 @@ module gc
// most gc_list_* functions for it.
#define NEXT_MASK_UNREACHABLE (1)

/* Get an object's GC head */
#define AS_GC(o) ((PyGC_Head *)(((char *)(o))-sizeof(PyGC_Head)))
#define AS_GC(op) _Py_AS_GC(op)
#define FROM_GC(gc) _Py_FROM_GC(gc)

/* Get the object given the GC head */
#define FROM_GC(g) ((PyObject *)(((char *)(g))+sizeof(PyGC_Head)))

static inline int
gc_is_collecting(PyGC_Head *g)
Expand Down Expand Up @@ -861,7 +859,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
* to imagine how calling it later could create a problem for us. wr
* is moved to wrcb_to_call in this case.
*/
if (gc_is_collecting(AS_GC(wr))) {
if (gc_is_collecting(AS_GC((PyObject *)wr))) {
/* it should already have been cleared above */
assert(wr->wr_object == Py_None);
continue;
Expand All @@ -873,7 +871,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
Py_INCREF(wr);

/* Move wr to wrcb_to_call, for the next pass. */
wrasgc = AS_GC(wr);
wrasgc = AS_GC((PyObject *)wr);
assert(wrasgc != next); /* wrasgc is reachable, but
next isn't, so they can't
be the same */
Expand Down Expand Up @@ -1909,7 +1907,7 @@ static PyObject *
gc_is_finalized(PyObject *module, PyObject *obj)
/*[clinic end generated code: output=e1516ac119a918ed input=201d0c58f69ae390]*/
{
if (_PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(AS_GC(obj))) {
if (_PyObject_IS_GC(obj) && _PyGC_FINALIZED(obj)) {
Py_RETURN_TRUE;
}
Py_RETURN_FALSE;
Expand Down Expand Up @@ -2409,7 +2407,7 @@ PyObject_GC_IsTracked(PyObject* obj)
int
PyObject_GC_IsFinalized(PyObject *obj)
{
if (_PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(AS_GC(obj))) {
if (_PyObject_IS_GC(obj) && _PyGC_FINALIZED(obj)) {
return 1;
}
return 0;
Expand Down